Improve error handling on Windows Launcher

This commit is contained in:
luiscuenca 2019-07-02 15:22:00 -07:00
parent a3ec365f6c
commit b877d20219
No known key found for this signature in database
GPG key ID: 2387ECD129A6961D
8 changed files with 234 additions and 104 deletions

View file

@ -21,6 +21,7 @@
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
@ -103,7 +104,7 @@ BEGIN
CTEXT "",IDC_MESSAGE2_LABEL,35,172,239,15,NOT WS_VISIBLE
CTEXT "",IDC_ACTION2_LABEL,15,147,278,25,NOT WS_VISIBLE
RTEXT "",IDC_TERMS,15,172,180,15,NOT WS_VISIBLE
CONTROL "",IDC_TERMS_LINK,"Button", BS_OWNERDRAW | BS_FLAT | NOT WS_VISIBLE | WS_TABSTOP,197,172,80,15
CONTROL "",IDC_TERMS_LINK,"Button",BS_OWNERDRAW | BS_FLAT | NOT WS_VISIBLE | WS_TABSTOP,197,172,80,15
CTEXT "",IDC_TROUBLE,65,203,174,15,NOT WS_VISIBLE
CONTROL "NEXT",IDC_BUTTON_NEXT,"Button",BS_OWNERDRAW | BS_FLAT | NOT WS_VISIBLE | WS_TABSTOP,107,158,94,16
CONTROL "Having Trouble?",IDC_TROUBLE_LINK,"Button",BS_OWNERDRAW | BS_FLAT | NOT WS_VISIBLE | WS_TABSTOP,126,203,56,11

View file

@ -32,19 +32,31 @@ CLauncherApp theApp;
// CLauncherApp initialization
BOOL CLauncherApp::InitInstance() {
// don't launch if already running
CreateMutex(NULL, TRUE, _T("HQ_Launcher_Mutex"));
if (GetLastError() == ERROR_ALREADY_EXISTS) {
return FALSE;
}
int iNumOfArgs;
LPWSTR* pArgs = CommandLineToArgvW(GetCommandLine(), &iNumOfArgs);
if (iNumOfArgs > 1 && CString(pArgs[1]).Compare(_T("--uninstall")) == 0) {
bool isUninstalling = false;
bool isRestarting = false;
if (iNumOfArgs > 1) {
if (CString(pArgs[1]).Compare(_T("--uninstall")) == 0) {
isUninstalling = true;
} else if (CString(pArgs[1]).Compare(_T("--restart")) == 0) {
isRestarting = true;
}
}
if (!isRestarting) {
// don't launch if already running
CreateMutex(NULL, TRUE, _T("HQ_Launcher_Mutex"));
if (GetLastError() == ERROR_ALREADY_EXISTS) {
return FALSE;
}
}
if (isUninstalling) {
_manager.uninstall();
} else {
_manager.init();
}
if (!_manager.installLauncher()) {
if (!_manager.hasFailed() && !_manager.installLauncher()) {
return FALSE;
}
installFont(IDR_FONT_REGULAR);

View file

@ -207,6 +207,10 @@ void CLauncherDlg::startProcess() {
default:
break;
}
if (error != LauncherUtils::DeleteDirError::NoErrorDeleting) {
theApp._manager.saveErrorLog();
theApp._manager.setFailed(true);
}
});
}
@ -230,7 +234,15 @@ afx_msg void CLauncherDlg::OnTermsClicked() {
}
afx_msg void CLauncherDlg::OnNextClicked() {
if (_drawStep != DrawStep::DrawChoose) {
if (_drawStep == DrawStep::DrawChoose) {
CString displayName;
m_username.GetWindowTextW(displayName);
theApp._manager.setDisplayName(displayName);
theApp._manager.addToLog(_T("Setting display name: " + displayName));
startProcess();
} else if (_drawStep == DrawStep::DrawError) {
theApp._manager.restartLauncher();
} else {
CString token;
CString username, password, orgname;
m_orgname.GetWindowTextW(orgname);
@ -261,12 +273,6 @@ afx_msg void CLauncherDlg::OnNextClicked() {
setDrawDialog(DrawStep::DrawLoginErrorOrg);
}
}
} else {
CString displayName;
m_username.GetWindowTextW(displayName);
theApp._manager.setDisplayName(displayName);
theApp._manager.addToLog(_T("Setting display name: " + displayName));
startProcess();
}
}
@ -318,7 +324,6 @@ void CLauncherDlg::drawVoxel(CHwndRenderTarget* pRenderTarget) {
pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
}
void CLauncherDlg::showWindows(std::vector<CStatic*> windows, bool show) {
for (auto window : windows) {
window->ShowWindow(show ? SW_SHOW : SW_HIDE);
@ -342,7 +347,7 @@ void CLauncherDlg::prepareLogin(DrawStep step) {
m_password.ShowWindow(SW_SHOW);
CString actionText = step == DrawStep::DrawLoginLogin ? _T("Please log in") : _T("Uh-oh, we have a problem");
CString messageText = step == DrawStep::DrawLoginLogin ? _T("Be sure you've uploaded your Avatar before signing in.") :
step == DrawStep::DrawLoginErrorCred ? _T("There is a problem with your credentials\n please try again.") : _T("There is a problem with your Organization name\n please try again.");
step == DrawStep::DrawLoginErrorCred ? _T("There is a problem with your credentials.\n Please try again.") : _T("There is a problem with your Organization name.\n Please try again.");
m_action_label->SetWindowTextW(actionText);
m_message_label->SetWindowTextW(messageText);
m_action_label->ShowWindow(SW_SHOW);
@ -354,7 +359,6 @@ void CLauncherDlg::prepareLogin(DrawStep step) {
}
void CLauncherDlg::prepareChoose() {
m_orgname.ShowWindow(SW_HIDE);
m_username.SetWindowTextW(_T(""));
@ -371,14 +375,7 @@ void CLauncherDlg::prepareChoose() {
m_terms_link.ShowWindow(SW_SHOW);
m_terms->SetWindowTextW(_T("By signing in, you agree to the High Fidelity"));
m_terms_link.SetWindowTextW(_T("Terms of Service"));
CRect rec;
m_btnNext.GetWindowRect(&rec);
ScreenToClient(&rec);
if (rec.top > 281) {
rec.bottom -= 35;
rec.top -= 35;
m_btnNext.MoveWindow(rec, FALSE);
}
setVerticalElement(&m_btnNext, -35, 0, false);
m_btnNext.ShowWindow(SW_SHOW);
}
@ -401,6 +398,7 @@ void CLauncherDlg::prepareProcess(DrawStep step) {
m_voxel->ShowWindow(SW_SHOW);
CString actionText = _T("");
CString messageText = _T("");
switch (step) {
case DrawStep::DrawProcessSetup:
actionText = _T("We're building your virtual HQ");
@ -422,6 +420,15 @@ void CLauncherDlg::prepareProcess(DrawStep step) {
actionText = _T("Uninstalling...");
messageText = _T("It'll take one sec.");
break;
case DrawStep::DrawError:
actionText = _T("Uh oh.");
messageText = _T("We seem to have a problem.\nPlease restart HQ.");
setVerticalElement(m_message2_label, 0, 5, false);
setVerticalElement(&m_btnNext, 10);
m_btnNext.ShowWindow(SW_SHOW);
break;
default:
break;
}
m_action2_label->SetWindowTextW(actionText);
m_message2_label->SetWindowTextW(messageText);
@ -429,9 +436,6 @@ void CLauncherDlg::prepareProcess(DrawStep step) {
m_message2_label->ShowWindow(SW_SHOW);
}
void CLauncherDlg::prepareError() {
}
BOOL CLauncherDlg::getTextFormat(int resID, TextFormat& formatOut) {
// Set default values for message
BOOL isText = TRUE;
@ -523,6 +527,8 @@ void CLauncherDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
btnName += _drawStep == DrawStep::DrawLoginLogin ? _T("NEXT") : _T("LOG IN");
int xpan = -20;
defrect = CRect(rect.left - xpan, rect.top, rect.right + xpan, rect.bottom);
} else if (_drawStep == DrawStep::DrawError) {
btnName += _T("RESTART");
} else {
btnName += _T("TRY AGAIN");
}
@ -594,49 +600,86 @@ BOOL CLauncherDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
void CLauncherDlg::OnTimer(UINT_PTR nIDEvent) {
const int CONSOLE_MAX_SHUTDOWN_TRY_COUNT = 10;
const int CONSOLE_DELTATIME_BETWEEN_TRYS = 10;
if (_drawStep == DrawStep::DrawProcessSetup ||
_drawStep == DrawStep::DrawProcessUpdate ||
_drawStep == DrawStep::DrawProcessUninstall) {
// Refresh
setDrawDialog(_drawStep, true);
if (theApp._manager.hasFailed() && _drawStep != DrawStep::DrawError) {
theApp._manager.saveErrorLog();
prepareProcess(DrawStep::DrawError);
setDrawDialog(DrawStep::DrawError, false);
}
if (_showSplash) {
if (_splashStep == 0){
if (theApp._manager.needsUninstall()) {
theApp._manager.addToLog(_T("Waiting to uninstall"));
setDrawDialog(DrawStep::DrawProcessUninstall);
} else {
theApp._manager.addToLog(_T("Start splash screen"));
setDrawDialog(DrawStep::DrawLogo);
if (_drawStep != DrawStep::DrawError) {
if (_drawStep == DrawStep::DrawProcessSetup ||
_drawStep == DrawStep::DrawProcessUpdate ||
_drawStep == DrawStep::DrawProcessUninstall) {
// Refresh
setDrawDialog(_drawStep, true);
}
if (_showSplash) {
if (_splashStep == 0) {
if (theApp._manager.needsUninstall()) {
theApp._manager.addToLog(_T("Waiting to uninstall"));
setDrawDialog(DrawStep::DrawProcessUninstall);
}
else {
theApp._manager.addToLog(_T("Start splash screen"));
setDrawDialog(DrawStep::DrawLogo);
}
}
} else if (_splashStep > 100) {
_showSplash = false;
if (theApp._manager.shouldShutDown()) {
if (_applicationWND != NULL) {
::SetForegroundWindow(_applicationWND);
::SetActiveWindow(_applicationWND);
else if (_splashStep > 100) {
_showSplash = false;
if (theApp._manager.shouldShutDown()) {
if (_applicationWND != NULL) {
::SetForegroundWindow(_applicationWND);
::SetActiveWindow(_applicationWND);
}
if (LauncherUtils::IsProcessRunning(L"interface.exe")) {
exit(0);
}
}
if (LauncherUtils::IsProcessRunning(L"interface.exe")) {
exit(0);
else if (theApp._manager.needsUpdate()) {
startProcess();
}
} else if (theApp._manager.needsUpdate()) {
startProcess();
} else if (theApp._manager.needsUninstall()) {
theApp._manager.uninstallApplication();
else if (theApp._manager.needsUninstall()) {
if (theApp._manager.uninstallApplication()) {
theApp._manager.addToLog(_T("HQ uninstalled successfully."));
exit(0);
}
else {
theApp._manager.addToLog(_T("HQ failed to uninstall."));
theApp._manager.setFailed(true);
}
}
else {
theApp._manager.addToLog(_T("Starting login"));
setDrawDialog(DrawStep::DrawLoginLogin);
}
}
_splashStep++;
} else if (theApp._manager.shouldShutDown()) {
if (LauncherUtils::IsProcessRunning(L"interface.exe")) {
exit(0);
} else {
theApp._manager.addToLog(_T("Starting login"));
setDrawDialog(DrawStep::DrawLoginLogin);
}
}
_splashStep++;
} else if (theApp._manager.shouldShutDown()) {
if (LauncherUtils::IsProcessRunning(L"interface.exe")) {
exit(0);
if (theApp._manager.shouldLaunch()) {
_applicationWND = theApp._manager.launchApplication();
}
}
if (theApp._manager.shouldLaunch()) {
_applicationWND = theApp._manager.launchApplication();
}
void CLauncherDlg::setVerticalElement(CWnd* element, int verticalOffset, int heightOffset, bool fromMainWindowBottom) {
CRect elementRec;
CRect windowRec;
if (element != NULL) {
element->GetWindowRect(&elementRec);
ScreenToClient(&elementRec);
int offset = verticalOffset;
if (fromMainWindowBottom) {
GetWindowRect(&windowRec);
ScreenToClient(&windowRec);
int currentDistance = windowRec.bottom - elementRec.bottom;
offset = currentDistance - verticalOffset;
}
elementRec.bottom = elementRec.bottom + offset + heightOffset;
elementRec.top = elementRec.top + offset;
element->MoveWindow(elementRec, FALSE);
}
}
@ -671,6 +714,7 @@ void CLauncherDlg::setDrawDialog(DrawStep step, BOOL isUpdate) {
m_pRenderTarget->EndDraw();
RedrawWindow();
break;
case DrawStep::DrawError:
case DrawStep::DrawProcessFinishHq:
case DrawStep::DrawProcessFinishUpdate:
case DrawStep::DrawProcessUpdate:

View file

@ -43,19 +43,18 @@ public:
void setDrawDialog(DrawStep step, BOOL isUpdate = FALSE);
// Dialog Data
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_LAUNCHER_DIALOG };
#endif
protected:
// Implementation
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
void startProcess();
void setCustomDialog();
// Implementation
protected:
void setVerticalElement(CWnd* element, int verticalOffset, int heightOffset = 0, bool fromMainWindowBottom = true);
BOOL getHQInfo(const CString& orgname);
DrawStep _drawStep { DrawStep::DrawLogo };
@ -100,7 +99,6 @@ protected:
void prepareLogin(DrawStep step);
void prepareProcess(DrawStep step);
void prepareChoose();
void prepareError();
void redrawBanner(const CEdit& edit, CStatic* banner);

View file

@ -27,20 +27,28 @@ LauncherManager::~LauncherManager()
void LauncherManager::init() {
initLog();
addToLog(_T("Getting most recent build"));
getMostRecentBuild(_latestApplicationURL, _latestVersion);
addToLog(_T("Latest version: ") + _latestVersion);
CString currentVersion;
if (isApplicationInstalled(currentVersion, _domainURL, _contentURL, _loggedIn) && _loggedIn) {
addToLog(_T("Installed version: ") + currentVersion);
if (_latestVersion.Compare(currentVersion) == 0) {
addToLog(_T("Already running most recent build. Launching interface.exe"));
_shouldLaunch = TRUE;
_shouldShutdown = TRUE;
} else {
addToLog(_T("New build found. Updating"));
_shouldUpdate = TRUE;
LauncherUtils::ResponseError error = getMostRecentBuild(_latestApplicationURL, _latestVersion);
if (error == LauncherUtils::ResponseError::NoError) {
addToLog(_T("Latest version: ") + _latestVersion);
CString currentVersion;
if (isApplicationInstalled(currentVersion, _domainURL, _contentURL, _loggedIn) && _loggedIn) {
addToLog(_T("Installed version: ") + currentVersion);
if (_latestVersion.Compare(currentVersion) == 0) {
addToLog(_T("Already running most recent build. Launching interface.exe"));
_shouldLaunch = TRUE;
_shouldShutdown = TRUE;
} else {
addToLog(_T("New build found. Updating"));
_shouldUpdate = TRUE;
}
}
} else {
_hasFailed = true;
CString msg;
msg.Format(_T("Getting most recent build has failed with error: %d"), error);
addToLog(msg);
}
}
BOOL LauncherManager::initLog() {
@ -74,8 +82,19 @@ void LauncherManager::closeLog() {
}
}
void LauncherManager::saveErrorLog() {
CString logPath = _logFile.GetFilePath();
CString errorLogPath;
auto result = getAndCreatePaths(PathType::Launcher_Directory, errorLogPath);
if (result) {
CString filename;
errorLogPath += _T("log_error.txt");
closeLog();
CopyFile(logPath, errorLogPath, FALSE);
}
}
BOOL LauncherManager::installLauncher() {
addToLog(_T("Installing Launcher."));
CString appPath;
BOOL result = getAndCreatePaths(PathType::Running_Path, appPath);
if (!result) {
@ -93,13 +112,14 @@ BOOL LauncherManager::installLauncher() {
if (!_shouldUninstall) {
// The installer is not running on the desired location and has to be installed
// Kill of running before self-copy
addToLog(_T("Installing Launcher."));
if (LauncherUtils::IsProcessRunning(LAUNCHER_EXE_FILENAME)) {
ShellExecute(NULL, NULL, L"taskkill", L"/F /T /IM " + LAUNCHER_EXE_FILENAME, NULL, SW_HIDE);
}
CopyFile(appPath, instalationPath, FALSE);
}
} else if (_shouldUninstall) {
addToLog(_T("Launching uninstall mode."));
addToLog(_T("Launching Uninstall mode."));
CString tempPath;
if (getAndCreatePaths(PathType::Temp_Directory, tempPath)) {
tempPath += _T("\\HQ_uninstaller_tmp.exe");
@ -111,6 +131,18 @@ BOOL LauncherManager::installLauncher() {
return TRUE;
}
BOOL LauncherManager::restartLauncher() {
addToLog(_T("Restarting Launcher."));
CString installDirectory;
if (getAndCreatePaths(PathType::Launcher_Directory, installDirectory)) {
CString installPath = installDirectory + LAUNCHER_EXE_FILENAME;
LauncherUtils::launchApplication(installPath, _T(" --restart"));
exit(0);
}
addToLog(_T("Error restarting Launcher."));
return FALSE;
}
BOOL LauncherManager::createShortcuts() {
CString desktopLnkPath;
addToLog(_T("Creating shortcuts."));
@ -395,8 +427,10 @@ BOOL LauncherManager::uninstallApplication() {
CString installDir;
getAndCreatePaths(PathType::Launcher_Directory, installDir);
BOOL success = LauncherUtils::deleteFileOrDirectory(installDir);
success = success && (deleteShortcuts());
success = success && (deleteApplicationRegistryKeys());
if (success) {
deleteShortcuts();
deleteApplicationRegistryKeys();
}
return success;
}
@ -425,7 +459,12 @@ BOOL LauncherManager::extractApplication() {
getAndCreatePaths(LauncherManager::PathType::Interface_Directory, installPath);
BOOL success = LauncherUtils::unzipFileOnThread(ZipType::ZipApplication, LauncherUtils::cStringToStd(_applicationZipPath),
LauncherUtils::cStringToStd(installPath), [&](int type, int size) {
onZipExtracted((ZipType)type, size);
if (size > 0) {
onZipExtracted((ZipType)type, size);
} else {
addToLog(_T("Error decompressing application zip file."));
_hasFailed = true;
}
});
if (success) {
addToLog(_T("Created thread for unzipping application."));
@ -452,7 +491,13 @@ BOOL LauncherManager::installContent() {
getAndCreatePaths(LauncherManager::PathType::Content_Directory, contentPath);
BOOL success = LauncherUtils::unzipFileOnThread(ZipType::ZipContent, contentZipFile,
LauncherUtils::cStringToStd(contentPath), [&](int type, int size) {
onZipExtracted((ZipType)type, size);
if (size > 0) {
addToLog(_T("Content zip decompresed."));
onZipExtracted((ZipType)type, size);
} else {
addToLog(_T("Error decompressing content zip file."));
_hasFailed = true;
}
});
if (success) {
addToLog(_T("Created thread for unzipping content."));
@ -469,8 +514,18 @@ BOOL LauncherManager::downloadFile(DownloadType type, const CString& url, CStrin
BOOL success = getAndCreatePaths(LauncherManager::PathType::Download_Directory, downloadDirectory);
outPath = downloadDirectory + fileName;
if (success) {
if (!LauncherUtils::downloadFileOnThread(type, url, outPath, [&](int type) {
onFileDownloaded((DownloadType)type);
addToLog(_T("Downloading: ") + url);
if (!LauncherUtils::downloadFileOnThread(type, url, outPath, [&](int type, bool error) {
if (!error) {
onFileDownloaded((DownloadType)type);
} else {
if (type == DownloadType::DownloadApplication) {
addToLog(_T("Error downloading content."));
} else {
addToLog(_T("Error downloading application."));
}
_hasFailed = true;
}
})) {
success = FALSE;
}

View file

@ -56,6 +56,7 @@ public:
BOOL initLog();
BOOL addToLog(const CString& line);
void closeLog();
void saveErrorLog();
BOOL getAndCreatePaths(PathType type, CString& outPath);
BOOL getInstalledVersion(const CString& path, CString& version);
BOOL isApplicationInstalled(CString& version, CString& domain,
@ -73,6 +74,7 @@ public:
HWND launchApplication();
BOOL uninstallApplication();
BOOL installLauncher();
BOOL restartLauncher();
// getters
const CString& getContentURL() const { return _contentURL; }
@ -84,6 +86,8 @@ public:
BOOL needsUninstall() { return _shouldUninstall; }
void setDisplayName(const CString& displayName) { _displayName = displayName; }
bool isLoggedIn() { return _loggedIn; }
bool hasFailed() { return _hasFailed; }
void setFailed(bool hasFailed) { _hasFailed = hasFailed; }
const CString& getLatestInterfaceURL() const { return _latestApplicationURL; }
void uninstall() { _shouldUninstall = true; };
@ -106,6 +110,7 @@ private:
CString _applicationZipPath;
CString _contentZipPath;
bool _loggedIn{ false };
bool _hasFailed{ false };
BOOL _shouldUpdate{ FALSE };
BOOL _shouldUninstall{ FALSE };
BOOL _shouldShutdown{ FALSE };

View file

@ -258,38 +258,54 @@ uint64_t LauncherUtils::extractZip(const std::string& zipFile, const std::string
}
int fileCount = (int)mz_zip_reader_get_num_files(&zip_archive);
if (fileCount == 0) {
theApp._manager.addToLog(_T("Zip archive has a file count of 0"));
{
CString msg;
msg.Format(_T("Zip archive has a file count of %d"), fileCount);
theApp._manager.addToLog(msg);
}
if (fileCount == 0) {
mz_zip_reader_end(&zip_archive);
return 0;
}
mz_zip_archive_file_stat file_stat;
if (!mz_zip_reader_file_stat(&zip_archive, 0, &file_stat)) {
theApp._manager.addToLog(_T("Zip archive cannot be stat'd"));
mz_zip_reader_end(&zip_archive);
return 0;
}
// Get root folder
CString lastDir = _T("");
uint64_t totalSize = 0;
bool _shouldFail = false;
for (int i = 0; i < fileCount; i++) {
if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) continue;
std::string filename = file_stat.m_filename;
std::replace(filename.begin(), filename.end(), '/', '\\');
CString fullFilename = CString(path.c_str()) + "\\" + CString(filename.c_str());
if (mz_zip_reader_is_file_a_directory(&zip_archive, i)) {
if (SHCreateDirectoryEx(NULL, fullFilename, NULL) || ERROR_ALREADY_EXISTS == GetLastError()) {
break;
} else {
continue;
int error = SHCreateDirectoryEx(NULL, fullFilename, NULL);
if (error == ERROR_BAD_PATHNAME ||
error == ERROR_FILENAME_EXCED_RANGE ||
error == ERROR_PATH_NOT_FOUND ||
error == ERROR_CANCELLED) {
CString msg;
msg.Format(_T("Unzipping error: %d creating folder: %s"), error, fullFilename);
theApp._manager.addToLog(msg);
mz_zip_reader_end(&zip_archive);
return 0;
}
continue;
}
CT2A destFile(fullFilename);
if (mz_zip_reader_extract_to_file(&zip_archive, i, destFile, 0)) {
totalSize += (uint64_t)file_stat.m_uncomp_size;
files.emplace_back(destFile);
} else {
CString msg;
msg.Format(_T("Error unzipping the file: %s"), fullFilename);
theApp._manager.addToLog(msg);
_shouldFail = true;
}
}
@ -421,11 +437,10 @@ DWORD WINAPI LauncherUtils::unzipThread(LPVOID lpParameter) {
return 0;
}
DWORD WINAPI LauncherUtils::downloadThread(LPVOID lpParameter)
{
DWORD WINAPI LauncherUtils::downloadThread(LPVOID lpParameter) {
DownloadThreadData& data = *((DownloadThreadData*)lpParameter);
auto hr = URLDownloadToFile(0, data._url, data._file, 0, NULL);
data.callback(data._type);
data.callback(data._type, hr != S_OK);
return 0;
}
@ -457,7 +472,7 @@ BOOL LauncherUtils::unzipFileOnThread(int type, const std::string& zipFile, cons
return FALSE;
}
BOOL LauncherUtils::downloadFileOnThread(int type, const CString& url, const CString& file, std::function<void(int)> callback) {
BOOL LauncherUtils::downloadFileOnThread(int type, const CString& url, const CString& file, std::function<void(int, bool)> callback) {
DWORD myThreadID;
DownloadThreadData* downloadThreadData = new DownloadThreadData();
downloadThreadData->_type = type;

View file

@ -41,10 +41,10 @@ public:
int _type;
CString _url;
CString _file;
std::function<void(int)> callback;
// function(type)
void setCallback(std::function<void(int)> fn) {
callback = std::bind(fn, std::placeholders::_1);
std::function<void(int, bool)> callback;
// function(type, errorType)
void setCallback(std::function<void(int, bool)> fn) {
callback = std::bind(fn, std::placeholders::_1, std::placeholders::_2);
}
};
@ -82,7 +82,7 @@ public:
static uint64_t extractZip(const std::string& zipFile, const std::string& path, std::vector<std::string>& files);
static BOOL deleteRegistryKey(const CString& registryPath);
static BOOL unzipFileOnThread(int type, const std::string& zipFile, const std::string& path, std::function<void(int, int)> callback);
static BOOL downloadFileOnThread(int type, const CString& url, const CString& file, std::function<void(int)> callback);
static BOOL downloadFileOnThread(int type, const CString& url, const CString& file, std::function<void(int, bool)> callback);
static BOOL deleteDirectoriesOnThread(const CString& applicationDir,
const CString& downloadsDir,
std::function<void(int)> callback);