0.8.24.dev test (not production!) version ready, updaters improved (no tdata copying while updating)
This commit is contained in:
		
							parent
							
								
									3373a2f382
								
							
						
					
					
						commit
						b6325ec9d4
					
				
					 9 changed files with 83 additions and 80 deletions
				
			
		| 
						 | 
				
			
			@ -1,9 +1,9 @@
 | 
			
		|||
@echo OFF
 | 
			
		||||
 | 
			
		||||
set "AppVersion=8023"
 | 
			
		||||
set "AppVersionStrSmall=0.8.23"
 | 
			
		||||
set "AppVersionStr=0.8.23"
 | 
			
		||||
set "AppVersionStrFull=0.8.23.0"
 | 
			
		||||
set "AppVersion=8024"
 | 
			
		||||
set "AppVersionStrSmall=0.8.24"
 | 
			
		||||
set "AppVersionStr=0.8.24"
 | 
			
		||||
set "AppVersionStrFull=0.8.24.0"
 | 
			
		||||
set "DevChannel=1"
 | 
			
		||||
 | 
			
		||||
if %DevChannel% neq 0 goto preparedev
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -124,19 +124,38 @@ void delFolder() {
 | 
			
		|||
	RemoveDirectory(delFolder.c_str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DWORD versionNum = 0, versionLen = 0, readLen = 0;
 | 
			
		||||
WCHAR versionStr[32] = { 0 };
 | 
			
		||||
 | 
			
		||||
bool update() {
 | 
			
		||||
	writeLog(L"Update started..");
 | 
			
		||||
 | 
			
		||||
	wstring updDir = L"tupdates\\temp", readyFilePath = L"tupdates\\temp\\ready";
 | 
			
		||||
	wstring updDir = L"tupdates\\temp", readyFilePath = L"tupdates\\temp\\ready", tdataDir = L"tupdates\\temp\\tdata";
 | 
			
		||||
	{
 | 
			
		||||
		HANDLE readyFile = CreateFile(readyFilePath.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
 | 
			
		||||
		if (readyFile != INVALID_HANDLE_VALUE) {
 | 
			
		||||
			CloseHandle(readyFile);
 | 
			
		||||
		} else {
 | 
			
		||||
			updDir = L"tupdates\\ready"; // old
 | 
			
		||||
			tdataDir = L"tupdates\\ready\\tdata";
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	HANDLE versionFile = CreateFile((tdataDir + L"\\version").c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
 | 
			
		||||
	if (versionFile != INVALID_HANDLE_VALUE) {
 | 
			
		||||
		if (ReadFile(versionFile, &versionNum, sizeof(DWORD), &readLen, NULL) != TRUE || readLen != sizeof(DWORD)) {
 | 
			
		||||
			versionNum = 0;
 | 
			
		||||
		} else if (ReadFile(versionFile, &versionLen, sizeof(DWORD), &readLen, NULL) != TRUE || readLen != sizeof(DWORD) || versionLen > 63) {
 | 
			
		||||
			versionNum = 0;
 | 
			
		||||
		} else if (ReadFile(versionFile, versionStr, versionLen, &readLen, NULL) != TRUE || readLen != versionLen) {
 | 
			
		||||
			versionNum = 0;
 | 
			
		||||
		}
 | 
			
		||||
		CloseHandle(versionFile);
 | 
			
		||||
		writeLog(L"Version file read.");
 | 
			
		||||
	} else {
 | 
			
		||||
		writeLog(L"Could not open version file to update registry :(");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	deque<wstring> dirs;
 | 
			
		||||
	dirs.push_back(updDir);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -167,13 +186,15 @@ bool update() {
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		do {
 | 
			
		||||
			if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
 | 
			
		||||
			wstring fname = dir + L"\\" + findData.cFileName;
 | 
			
		||||
			if (fname.substr(0, tdataDir.size()) == tdataDir && (fname.size() <= tdataDir.size() || fname.at(tdataDir.size()) == '/')) {
 | 
			
		||||
				writeLog(L"Skipped 'tdata' path '" + fname + L"'");
 | 
			
		||||
			} else if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
 | 
			
		||||
				if (findData.cFileName != wstring(L".") && findData.cFileName != wstring(L"..")) {
 | 
			
		||||
					dirs.push_back(dir + L"\\" + findData.cFileName);
 | 
			
		||||
					writeLog(L"Added dir '" + dir + L"\\" + findData.cFileName + L"' in update tree..");
 | 
			
		||||
					dirs.push_back(fname);
 | 
			
		||||
					writeLog(L"Added dir '" + fname + L"' in update tree..");
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				wstring fname = dir + L"\\" + findData.cFileName;
 | 
			
		||||
				wstring tofname = updateTo + fname.substr(updDir.size() + 1);
 | 
			
		||||
				if (equal(tofname, exeName)) { // bad update - has Updater.exe - delete all dir
 | 
			
		||||
					writeLog(L"Error: bad update, has Updater.exe! '" + tofname + L"' equal '" + exeName + L"'");
 | 
			
		||||
| 
						 | 
				
			
			@ -246,73 +267,57 @@ bool update() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void updateRegistry() {
 | 
			
		||||
	HANDLE versionFile = CreateFile((updateTo + L"tdata\\version").c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
 | 
			
		||||
	if (versionFile != INVALID_HANDLE_VALUE) {
 | 
			
		||||
	if (versionNum) {
 | 
			
		||||
		writeLog(L"Updating registry..");
 | 
			
		||||
		DWORD versionNum = 0, versionLen = 0, readLen = 0;
 | 
			
		||||
		WCHAR versionStr[32];
 | 
			
		||||
		if (ReadFile(versionFile, &versionNum, sizeof(DWORD), &readLen, NULL) != TRUE || readLen != sizeof(DWORD)) {
 | 
			
		||||
			versionNum = 0;
 | 
			
		||||
		} else if (ReadFile(versionFile, &versionLen, sizeof(DWORD), &readLen, NULL) != TRUE || readLen != sizeof(DWORD) || versionLen > 63) {
 | 
			
		||||
			versionNum = 0;
 | 
			
		||||
		} else if (ReadFile(versionFile, versionStr, versionLen, &readLen, NULL) != TRUE || readLen != versionLen) {
 | 
			
		||||
			versionNum = 0;
 | 
			
		||||
		}
 | 
			
		||||
		CloseHandle(versionFile);
 | 
			
		||||
		writeLog(L"Version file read.");
 | 
			
		||||
		if (versionNum) {
 | 
			
		||||
			versionStr[versionLen / 2] = 0;
 | 
			
		||||
			HKEY rkey;
 | 
			
		||||
			LSTATUS status = RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{53F49750-6209-4FBF-9CA8-7A333C87D1ED}_is1", 0, KEY_QUERY_VALUE | KEY_SET_VALUE, &rkey);
 | 
			
		||||
			if (status == ERROR_SUCCESS) {
 | 
			
		||||
				writeLog(L"Checking registry install location..");
 | 
			
		||||
				static const int bufSize = 4096;
 | 
			
		||||
				DWORD locationType, locationSize = bufSize * 2;
 | 
			
		||||
				WCHAR locationStr[bufSize], exp[bufSize];
 | 
			
		||||
				if (RegQueryValueEx(rkey, L"InstallLocation", 0, &locationType, (BYTE*)locationStr, &locationSize) == ERROR_SUCCESS) {
 | 
			
		||||
					locationSize /= 2;
 | 
			
		||||
					if (locationStr[locationSize - 1]) {
 | 
			
		||||
						locationStr[locationSize++] = 0;
 | 
			
		||||
		versionStr[versionLen / 2] = 0;
 | 
			
		||||
		HKEY rkey;
 | 
			
		||||
		LSTATUS status = RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{53F49750-6209-4FBF-9CA8-7A333C87D1ED}_is1", 0, KEY_QUERY_VALUE | KEY_SET_VALUE, &rkey);
 | 
			
		||||
		if (status == ERROR_SUCCESS) {
 | 
			
		||||
			writeLog(L"Checking registry install location..");
 | 
			
		||||
			static const int bufSize = 4096;
 | 
			
		||||
			DWORD locationType, locationSize = bufSize * 2;
 | 
			
		||||
			WCHAR locationStr[bufSize], exp[bufSize];
 | 
			
		||||
			if (RegQueryValueEx(rkey, L"InstallLocation", 0, &locationType, (BYTE*)locationStr, &locationSize) == ERROR_SUCCESS) {
 | 
			
		||||
				locationSize /= 2;
 | 
			
		||||
				if (locationStr[locationSize - 1]) {
 | 
			
		||||
					locationStr[locationSize++] = 0;
 | 
			
		||||
				}
 | 
			
		||||
				if (locationType == REG_EXPAND_SZ) {
 | 
			
		||||
					DWORD copy = ExpandEnvironmentStrings(locationStr, exp, bufSize);
 | 
			
		||||
					if (copy <= bufSize) {
 | 
			
		||||
						memcpy(locationStr, exp, copy * sizeof(WCHAR));
 | 
			
		||||
					}
 | 
			
		||||
					if (locationType == REG_EXPAND_SZ) {
 | 
			
		||||
						DWORD copy = ExpandEnvironmentStrings(locationStr, exp, bufSize);
 | 
			
		||||
						if (copy <= bufSize) {
 | 
			
		||||
							memcpy(locationStr, exp, copy * sizeof(WCHAR));
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					if (locationType == REG_EXPAND_SZ || locationType == REG_SZ) {
 | 
			
		||||
						if (PathCanonicalize(exp, locationStr) == TRUE) {
 | 
			
		||||
							memcpy(locationStr, exp, bufSize * sizeof(WCHAR));
 | 
			
		||||
							if (GetFullPathName(L".", bufSize, exp, 0) < bufSize) {
 | 
			
		||||
								wstring installpath = locationStr, mypath = exp;
 | 
			
		||||
								if (installpath == mypath + L"\\" || true) { // always update reg info, if we found it
 | 
			
		||||
									WCHAR nameStr[bufSize], dateStr[bufSize], publisherStr[bufSize], icongroupStr[bufSize];
 | 
			
		||||
									SYSTEMTIME stLocalTime;
 | 
			
		||||
									GetLocalTime(&stLocalTime);
 | 
			
		||||
									RegSetValueEx(rkey, L"DisplayVersion", 0, REG_SZ, (BYTE*)versionStr, ((versionLen / 2) + 1) * sizeof(WCHAR));
 | 
			
		||||
									wsprintf(nameStr, L"Telegram Desktop version %s", versionStr);
 | 
			
		||||
									RegSetValueEx(rkey, L"DisplayName", 0, REG_SZ, (BYTE*)nameStr, (wcslen(nameStr) + 1) * sizeof(WCHAR));
 | 
			
		||||
									wsprintf(publisherStr, L"Telegram Messenger LLP");
 | 
			
		||||
									RegSetValueEx(rkey, L"Publisher", 0, REG_SZ, (BYTE*)publisherStr, (wcslen(publisherStr) + 1) * sizeof(WCHAR));
 | 
			
		||||
									wsprintf(icongroupStr, L"Telegram Desktop");
 | 
			
		||||
									RegSetValueEx(rkey, L"Inno Setup: Icon Group", 0, REG_SZ, (BYTE*)icongroupStr, (wcslen(icongroupStr) + 1) * sizeof(WCHAR));
 | 
			
		||||
									wsprintf(dateStr, L"%04d%02d%02d", stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay);
 | 
			
		||||
									RegSetValueEx(rkey, L"InstallDate", 0, REG_SZ, (BYTE*)dateStr, (wcslen(dateStr) + 1) * sizeof(WCHAR));
 | 
			
		||||
				}
 | 
			
		||||
				if (locationType == REG_EXPAND_SZ || locationType == REG_SZ) {
 | 
			
		||||
					if (PathCanonicalize(exp, locationStr) == TRUE) {
 | 
			
		||||
						memcpy(locationStr, exp, bufSize * sizeof(WCHAR));
 | 
			
		||||
						if (GetFullPathName(L".", bufSize, exp, 0) < bufSize) {
 | 
			
		||||
							wstring installpath = locationStr, mypath = exp;
 | 
			
		||||
							if (installpath == mypath + L"\\" || true) { // always update reg info, if we found it
 | 
			
		||||
								WCHAR nameStr[bufSize], dateStr[bufSize], publisherStr[bufSize], icongroupStr[bufSize];
 | 
			
		||||
								SYSTEMTIME stLocalTime;
 | 
			
		||||
								GetLocalTime(&stLocalTime);
 | 
			
		||||
								RegSetValueEx(rkey, L"DisplayVersion", 0, REG_SZ, (BYTE*)versionStr, ((versionLen / 2) + 1) * sizeof(WCHAR));
 | 
			
		||||
								wsprintf(nameStr, L"Telegram Desktop version %s", versionStr);
 | 
			
		||||
								RegSetValueEx(rkey, L"DisplayName", 0, REG_SZ, (BYTE*)nameStr, (wcslen(nameStr) + 1) * sizeof(WCHAR));
 | 
			
		||||
								wsprintf(publisherStr, L"Telegram Messenger LLP");
 | 
			
		||||
								RegSetValueEx(rkey, L"Publisher", 0, REG_SZ, (BYTE*)publisherStr, (wcslen(publisherStr) + 1) * sizeof(WCHAR));
 | 
			
		||||
								wsprintf(icongroupStr, L"Telegram Desktop");
 | 
			
		||||
								RegSetValueEx(rkey, L"Inno Setup: Icon Group", 0, REG_SZ, (BYTE*)icongroupStr, (wcslen(icongroupStr) + 1) * sizeof(WCHAR));
 | 
			
		||||
								wsprintf(dateStr, L"%04d%02d%02d", stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay);
 | 
			
		||||
								RegSetValueEx(rkey, L"InstallDate", 0, REG_SZ, (BYTE*)dateStr, (wcslen(dateStr) + 1) * sizeof(WCHAR));
 | 
			
		||||
 | 
			
		||||
									WCHAR *appURL = L"https://desktop.telegram.org";
 | 
			
		||||
									RegSetValueEx(rkey, L"HelpLink", 0, REG_SZ, (BYTE*)appURL, (wcslen(appURL) + 1) * sizeof(WCHAR));
 | 
			
		||||
									RegSetValueEx(rkey, L"URLInfoAbout", 0, REG_SZ, (BYTE*)appURL, (wcslen(appURL) + 1) * sizeof(WCHAR));
 | 
			
		||||
									RegSetValueEx(rkey, L"URLUpdateInfo", 0, REG_SZ, (BYTE*)appURL, (wcslen(appURL) + 1) * sizeof(WCHAR));
 | 
			
		||||
								}
 | 
			
		||||
								WCHAR *appURL = L"https://desktop.telegram.org";
 | 
			
		||||
								RegSetValueEx(rkey, L"HelpLink", 0, REG_SZ, (BYTE*)appURL, (wcslen(appURL) + 1) * sizeof(WCHAR));
 | 
			
		||||
								RegSetValueEx(rkey, L"URLInfoAbout", 0, REG_SZ, (BYTE*)appURL, (wcslen(appURL) + 1) * sizeof(WCHAR));
 | 
			
		||||
								RegSetValueEx(rkey, L"URLUpdateInfo", 0, REG_SZ, (BYTE*)appURL, (wcslen(appURL) + 1) * sizeof(WCHAR));
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				RegCloseKey(rkey);
 | 
			
		||||
			}
 | 
			
		||||
			RegCloseKey(rkey);
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		writeLog(L"Could not open version file to update registry :(");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -271,8 +271,6 @@ bool update() {
 | 
			
		|||
                    }
 | 
			
		||||
					if (fname == readyFilePath) {
 | 
			
		||||
						writeLog("Skipped ready file '%s'", fname.c_str());
 | 
			
		||||
                    } else if (fname == versionFilePath) {
 | 
			
		||||
                        writeLog("Skipped version file '%s'", fname.c_str());
 | 
			
		||||
                    } else {
 | 
			
		||||
						from.push_back(fname);
 | 
			
		||||
						to.push_back(tofname);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ void openLog() {
 | 
			
		|||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	NSDateFormatter *fmt = [[NSDateFormatter alloc] initWithDateFormat:@"DebugLogs/%Y%m%d %H%M%S_upd.txt" allowNaturalLanguage:NO];
 | 
			
		||||
	NSDateFormatter *fmt = [[NSDateFormatter alloc] initWithDateFormat:@"DebugLogs/%Y%m%d_%H%M%S_upd.txt" allowNaturalLanguage:NO];
 | 
			
		||||
	NSString *logPath = [workDir stringByAppendingString:[fmt stringFromDate:[NSDate date]]];
 | 
			
		||||
	[[NSFileManager defaultManager] createFileAtPath:logPath contents:nil attributes:nil];
 | 
			
		||||
	_logFile = [NSFileHandle fileHandleForWritingAtPath:logPath];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,8 +17,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
 | 
			
		|||
*/
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
static const int32 AppVersion = 8023;
 | 
			
		||||
static const wchar_t *AppVersionStr = L"0.8.23";
 | 
			
		||||
static const int32 AppVersion = 8024;
 | 
			
		||||
static const wchar_t *AppVersionStr = L"0.8.24";
 | 
			
		||||
static const bool DevChannel = true;
 | 
			
		||||
 | 
			
		||||
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,7 @@
 | 
			
		|||
	<key>CFBundlePackageType</key>
 | 
			
		||||
	<string>APPL</string>
 | 
			
		||||
	<key>CFBundleShortVersionString</key>
 | 
			
		||||
	<string>0.8.23</string>
 | 
			
		||||
	<string>0.8.24</string>
 | 
			
		||||
        <key>LSMinimumSystemVersion</key>
 | 
			
		||||
        <string>$(MACOSX_DEPLOYMENT_TARGET)</string>
 | 
			
		||||
	<key>CFBundleSignature</key>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -1703,7 +1703,7 @@
 | 
			
		|||
			buildSettings = {
 | 
			
		||||
				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 | 
			
		||||
				COPY_PHASE_STRIP = NO;
 | 
			
		||||
				CURRENT_PROJECT_VERSION = 0.8.23;
 | 
			
		||||
				CURRENT_PROJECT_VERSION = 0.8.24;
 | 
			
		||||
				DEBUG_INFORMATION_FORMAT = dwarf;
 | 
			
		||||
				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
 | 
			
		||||
				GCC_OPTIMIZATION_LEVEL = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -1721,7 +1721,7 @@
 | 
			
		|||
			buildSettings = {
 | 
			
		||||
				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
 | 
			
		||||
				COPY_PHASE_STRIP = YES;
 | 
			
		||||
				CURRENT_PROJECT_VERSION = 0.8.23;
 | 
			
		||||
				CURRENT_PROJECT_VERSION = 0.8.24;
 | 
			
		||||
				GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
 | 
			
		||||
				GCC_OPTIMIZATION_LEVEL = fast;
 | 
			
		||||
				GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h;
 | 
			
		||||
| 
						 | 
				
			
			@ -1747,10 +1747,10 @@
 | 
			
		|||
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 | 
			
		||||
				CODE_SIGN_IDENTITY = "";
 | 
			
		||||
				COPY_PHASE_STRIP = NO;
 | 
			
		||||
				CURRENT_PROJECT_VERSION = 0.8.23;
 | 
			
		||||
				CURRENT_PROJECT_VERSION = 0.8.24;
 | 
			
		||||
				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 | 
			
		||||
				DYLIB_COMPATIBILITY_VERSION = 0.8;
 | 
			
		||||
				DYLIB_CURRENT_VERSION = 0.8.23;
 | 
			
		||||
				DYLIB_CURRENT_VERSION = 0.8.24;
 | 
			
		||||
				ENABLE_STRICT_OBJC_MSGSEND = YES;
 | 
			
		||||
				FRAMEWORK_SEARCH_PATHS = "";
 | 
			
		||||
				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
 | 
			
		||||
| 
						 | 
				
			
			@ -1890,10 +1890,10 @@
 | 
			
		|||
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 | 
			
		||||
				CODE_SIGN_IDENTITY = "";
 | 
			
		||||
				COPY_PHASE_STRIP = NO;
 | 
			
		||||
				CURRENT_PROJECT_VERSION = 0.8.23;
 | 
			
		||||
				CURRENT_PROJECT_VERSION = 0.8.24;
 | 
			
		||||
				DEBUG_INFORMATION_FORMAT = dwarf;
 | 
			
		||||
				DYLIB_COMPATIBILITY_VERSION = 0.8;
 | 
			
		||||
				DYLIB_CURRENT_VERSION = 0.8.23;
 | 
			
		||||
				DYLIB_CURRENT_VERSION = 0.8.24;
 | 
			
		||||
				ENABLE_STRICT_OBJC_MSGSEND = YES;
 | 
			
		||||
				FRAMEWORK_SEARCH_PATHS = "";
 | 
			
		||||
				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,2 +1,2 @@
 | 
			
		|||
echo 8023 0.8.23 1
 | 
			
		||||
echo 8024 0.8.24 1
 | 
			
		||||
# AppVersion AppVersionStr DevChannel
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue