From f1fa2f8cd2632ac409ccb5f6d9e77cefc2149211 Mon Sep 17 00:00:00 2001 From: danteruiz Date: Tue, 24 Sep 2019 18:45:42 -0700 Subject: [PATCH] adding windows auto-updater --- launchers/qt/CMakeLists.txt | 22 ++++-- launchers/qt/src/Helper.cpp | 49 ------------- .../{darwin/Helper.mm => Helper_darwin.mm} | 0 launchers/qt/src/Helper_windows.cpp | 70 +++++++++++++++++++ launchers/qt/src/Launcher.cpp | 1 + .../qt/src/LauncherInstaller_windows.cpp | 43 ++++++++++++ launchers/qt/src/LauncherInstaller_windows.h | 16 +++++ launchers/qt/src/LauncherState.cpp | 25 +++++-- launchers/qt/src/LauncherState.h | 2 + .../NSTask+NSTaskExecveAdditions.h | 0 .../NSTask+NSTaskExecveAdditions.m | 0 launchers/qt/src/main.cpp | 18 +++++ 12 files changed, 188 insertions(+), 58 deletions(-) rename launchers/qt/src/{darwin/Helper.mm => Helper_darwin.mm} (100%) create mode 100644 launchers/qt/src/Helper_windows.cpp create mode 100644 launchers/qt/src/LauncherInstaller_windows.cpp create mode 100644 launchers/qt/src/LauncherInstaller_windows.h rename launchers/qt/src/{darwin => }/NSTask+NSTaskExecveAdditions.h (100%) rename launchers/qt/src/{darwin => }/NSTask+NSTaskExecveAdditions.m (100%) diff --git a/launchers/qt/CMakeLists.txt b/launchers/qt/CMakeLists.txt index 86654930c5..169240c647 100644 --- a/launchers/qt/CMakeLists.txt +++ b/launchers/qt/CMakeLists.txt @@ -11,7 +11,6 @@ set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -#set(CMAKE_AUTOUIC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) include("cmake/init.cmake") @@ -110,6 +109,8 @@ add_custom_command( COMMAND "${_qt5Core_install_prefix}/bin/rcc" ARGS ${RESOURCES_QRC} -binary -o ${RESOURCES_RCC}) +QT5_ADD_RESOURCES(RES_SOURCES ${RESOURCES_QRC}) + list(APPEND GENERATE_QRC_DEPENDS ${RESOURCES_RCC}) add_custom_target(resources ALL DEPENDS ${GENERATE_QRC_DEPENDS}) @@ -134,14 +135,23 @@ set(src_files src/Helper.cpp deps/miniz/miniz.h deps/miniz/miniz.cpp + ${RES_SOURCES} ) if (APPLE) set(src_files ${src_files} - src/darwin/Helper.mm - src/darwin/NSTask+NSTaskExecveAdditions.h - src/darwin/NSTask+NSTaskExecveAdditions.m + src/Helper_darwin.mm + src/NSTask+NSTaskExecveAdditions.h + src/NSTask+NSTaskExecveAdditions.m + ) +endif() + +if (WIN32) + set(src_files ${src_files} + src/Helper_windows.cpp + src/LauncherInstaller_windows.h + src/LauncherInstaller_windows.cpp ) endif() set(TARGET_NAME ${PROJECT_NAME}) @@ -149,7 +159,7 @@ set(TARGET_NAME ${PROJECT_NAME}) set_packaging_parameters() if (WIN32) - add_executable(${PROJECT_NAME} ${src_files}) + add_executable(${PROJECT_NAME} ${src_files} build/resources.qrc) elseif (APPLE) set_target_properties(${this_target} PROPERTIES MACOSX_BUNDLE_INFO_PLIST MacOSXBundleInfo.plist.in) @@ -220,6 +230,8 @@ else() message("Use resource.rcc path: qrc:/") endif() +target_compile_definitions(${PROJECT_NAME} PRIVATE LAUNCHER_BUILD_VERSION="${BUILD_VERSION}") + if (APPLE) install( TARGETS HQLauncher diff --git a/launchers/qt/src/Helper.cpp b/launchers/qt/src/Helper.cpp index f8e8b03505..f056676d43 100644 --- a/launchers/qt/src/Helper.cpp +++ b/launchers/qt/src/Helper.cpp @@ -7,55 +7,6 @@ #include #include -#if defined(Q_OS_WIN) - -#include - -void launchClient(const QString& clientPath, const QString& homePath, const QString& defaultScriptsPath, - const QString& displayName, const QString& contentCachePath, QString loginResponseToken) { - - // TODO Fix parameters - QString params = "--url \"" + homePath + "\"" - + " --setBookmark \"hqhome=" + homePath + "\"" - + " --defaultScriptsOverride \"" + defaultScriptsPath + "\"" - + " --displayName \"" + displayName + "\"" - + " --cache \"" + contentCachePath + "\""; - - if (!loginResponseToken.isEmpty()) { - params += " --tokens \"" + loginResponseToken.replace("\"", "\\\"") + "\""; - } - - STARTUPINFO si; - PROCESS_INFORMATION pi; - - // set the size of the structures - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - ZeroMemory(&pi, sizeof(pi)); - - // start the program up - BOOL success = CreateProcess( - clientPath.toUtf8().data(), - params.toUtf8().data(), - nullptr, // Process handle not inheritable - nullptr, // Thread handle not inheritable - FALSE, // Set handle inheritance to FALSE - CREATE_NEW_CONSOLE, // Opens file in a separate console - nullptr, // Use parent's environment block - nullptr, // Use parent's starting directory - &si, // Pointer to STARTUPINFO structure - &pi // Pointer to PROCESS_INFORMATION structure - ); - - // Close process and thread handles. - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - - QCoreApplication::instance()->quit(); -} -#endif - - void swapLaunchers(const QString& oldLauncherPath, const QString& newLauncherPath) { if (!(QFileInfo::exists(oldLauncherPath) && QFileInfo::exists(newLauncherPath))) { diff --git a/launchers/qt/src/darwin/Helper.mm b/launchers/qt/src/Helper_darwin.mm similarity index 100% rename from launchers/qt/src/darwin/Helper.mm rename to launchers/qt/src/Helper_darwin.mm diff --git a/launchers/qt/src/Helper_windows.cpp b/launchers/qt/src/Helper_windows.cpp new file mode 100644 index 0000000000..cb3671f274 --- /dev/null +++ b/launchers/qt/src/Helper_windows.cpp @@ -0,0 +1,70 @@ +#include "Helper.h" + +#include +#include + +void launchClient(const QString& clientPath, const QString& homePath, const QString& defaultScriptsPath, + const QString& displayName, const QString& contentCachePath, QString loginResponseToken) { + + // TODO Fix parameters + QString params = "--url \"" + homePath + "\"" + + " --setBookmark \"hqhome=" + homePath + "\"" + + " --defaultScriptsOverride \"" + defaultScriptsPath + "\"" + + " --displayName \"" + displayName + "\"" + + " --cache \"" + contentCachePath + "\""; + + if (!loginResponseToken.isEmpty()) { + params += " --tokens \"" + loginResponseToken.replace("\"", "\\\"") + "\""; + } + + STARTUPINFO si; + PROCESS_INFORMATION pi; + + // set the size of the structures + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + ZeroMemory(&pi, sizeof(pi)); + + // start the program up + BOOL success = CreateProcess( + clientPath.toUtf8().data(), + params.toUtf8().data(), + nullptr, // Process handle not inheritable + nullptr, // Thread handle not inheritable + FALSE, // Set handle inheritance to FALSE + CREATE_NEW_CONSOLE, // Opens file in a separate console + nullptr, // Use parent's environment block + nullptr, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi // Pointer to PROCESS_INFORMATION structure + ); + + // Close process and thread handles. + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + + QCoreApplication::instance()->quit(); +} + +void launchAutoUpdater(const QString& autoUpdaterPath) { + QString params = "--restart --noUpdate"; + STARTUPINFO si; + PROCESS_INFORMATION pi; + + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + ZeroMemory(&pi, sizeof(pi)); + + BOOL success = CreateProcess( + autoUpdaterPath.toUtf8().data(), + params.toUtf8().data(), + nullptr, // Process handle not inheritable + nullptr, // Thread handle not inheritable + FALSE, // Set handle inheritance to FALSE + CREATE_NEW_CONSOLE, // Opens file in a separate console + nullptr, // Use parent's environment block + nullptr, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi // Pointer to PROCESS_INFORMATION structure + ); +} diff --git a/launchers/qt/src/Launcher.cpp b/launchers/qt/src/Launcher.cpp index 2d5fd8dc21..8ad9085cc8 100644 --- a/launchers/qt/src/Launcher.cpp +++ b/launchers/qt/src/Launcher.cpp @@ -9,6 +9,7 @@ #include "PathUtils.h" Launcher::Launcher(int& argc, char**argv) : QGuiApplication(argc, argv) { + Q_INIT_RESOURCE(resources); QString resourceBinaryLocation = QGuiApplication::applicationDirPath() + "/resources.rcc"; qDebug() << "resources.rcc path: " << resourceBinaryLocation; QResource::registerResource(resourceBinaryLocation); diff --git a/launchers/qt/src/LauncherInstaller_windows.cpp b/launchers/qt/src/LauncherInstaller_windows.cpp new file mode 100644 index 0000000000..4a3f819c23 --- /dev/null +++ b/launchers/qt/src/LauncherInstaller_windows.cpp @@ -0,0 +1,43 @@ +#include "LauncherInstaller_windows.h" + +#include + +#include +#include +#include +#include + +LauncherInstaller::LauncherInstaller(const QString& applicationFilePath) { + _launcherInstallDir = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/HQ"; + qDebug() << "Launcher install dir: " << _launcherInstallDir.absolutePath(); + _launcherInstallDir.mkpath(_launcherInstallDir.absolutePath()); + QFileInfo fileInfo(applicationFilePath); + _launcherRunningFilePath = fileInfo.absoluteFilePath(); + _launcherRunningDirPath = fileInfo.absoluteDir().absolutePath(); + qDebug() << "Launcher running file path: " << _launcherRunningFilePath; + qDebug() << "Launcher running dir path: " << _launcherRunningDirPath; +} + +bool LauncherInstaller::runningOutsideOfInstallDir() { + return (QString::compare(_launcherInstallDir.absolutePath(), _launcherRunningDirPath) != 0); +} + +void LauncherInstaller::install() { + if (runningOutsideOfInstallDir()) { + qDebug() << "Installing HQ Launcher...."; + QString oldLauncherPath = _launcherInstallDir.absolutePath() + "/HQ Launcher.exe"; + + if (QFile::exists(oldLauncherPath)) { + bool didRemove = QFile::remove(oldLauncherPath); + qDebug() << "did remove file: " << didRemove; + } + bool success = QFile::copy(_launcherRunningFilePath, oldLauncherPath); + if (success) { + qDebug() << "successful"; + } else { + qDebug() << "not successful"; + } + } +} + +void LauncherInstaller::uninstall() {} diff --git a/launchers/qt/src/LauncherInstaller_windows.h b/launchers/qt/src/LauncherInstaller_windows.h new file mode 100644 index 0000000000..1aa10ce876 --- /dev/null +++ b/launchers/qt/src/LauncherInstaller_windows.h @@ -0,0 +1,16 @@ +#pragma once + +#include +class LauncherInstaller { +public: + LauncherInstaller(const QString& applicationFilePath); + ~LauncherInstaller() = default; + + void install(); + void uninstall(); +private: + bool runningOutsideOfInstallDir(); + QDir _launcherInstallDir; + QString _launcherRunningFilePath; + QString _launcherRunningDirPath; +}; diff --git a/launchers/qt/src/LauncherState.cpp b/launchers/qt/src/LauncherState.cpp index 91b91b785c..1a8023e236 100644 --- a/launchers/qt/src/LauncherState.cpp +++ b/launchers/qt/src/LauncherState.cpp @@ -8,6 +8,7 @@ #include #endif #include +#include #include @@ -69,7 +70,7 @@ bool LatestBuilds::getBuild(QString tag, Build* outBuild) { } static const std::array QML_FILE_FOR_UI_STATE = - { { "qml/SplashScreen.qml", "qml/HFBase/CreateAccountBase.qml", "DisplayName.qml", + { { "SplashScreen.qml", "qml/HFBase/CreateAccountBase.qml", "DisplayName.qml", "qml/Download.qml", "qml/DownloadFinished.qml", "qml/HFBase/Error.qml" } }; void LauncherState::ASSERT_STATE(LauncherState::ApplicationState state) { @@ -220,9 +221,17 @@ void LauncherState::receivedBuildsReply() { } } + if (shouldDownloadLauncher()) { + downloadLauncher(); + } getCurrentClientVersion(); } + +bool LauncherState::shouldDownloadLauncher() { + return _latestBuilds.launcherBuild.latestVersion != atoi(LAUNCHER_BUILD_VERSION); +} + void LauncherState::getCurrentClientVersion() { ASSERT_STATE(ApplicationState::RequestingBuilds); @@ -453,14 +462,17 @@ void LauncherState::downloadClient() { void LauncherState::launcherDownloadComplete() { _launcherZipFile.close(); + +#ifdef Q_OS_MAC installLauncher(); +#elif defined(Q_OS_WIN) + //launchAutoUpdater(_launcherZipFile.fileName()); +#endif } void LauncherState::clientDownloadComplete() { ASSERT_STATE(ApplicationState::DownloadingClient); - _clientZipFile.close(); - installClient(); } @@ -501,7 +513,11 @@ void LauncherState::downloadLauncher() { auto request = new QNetworkRequest(QUrl(_latestBuilds.launcherBuild.installerZipURL)); auto reply = _networkAccessManager.get(*request); +#ifdef Q_OS_MAC _launcherZipFile.setFileName(_launcherDirectory.absoluteFilePath("launcher.zip")); +#elif defined(Q_OS_WIN) + _launcherZipFile.setFileName(_launcherDirectory.absoluteFilePath("launcher.exe")); +#endif qDebug() << "opening " << _launcherZipFile.fileName(); @@ -525,8 +541,9 @@ void LauncherState::downloadLauncher() { } void LauncherState::installLauncher() { - auto installDir = _launcherDirectory.absoluteFilePath("launcher_install"); + _launcherDirectory.rmpath("launcher_install"); _launcherDirectory.mkpath("launcher_install"); + auto installDir = _launcherDirectory.absoluteFilePath("launcher_install"); qDebug() << "Uzipping " << _launcherZipFile.fileName() << " to " << installDir; diff --git a/launchers/qt/src/LauncherState.h b/launchers/qt/src/LauncherState.h index c20dd99518..f3a3c4a313 100644 --- a/launchers/qt/src/LauncherState.h +++ b/launchers/qt/src/LauncherState.h @@ -146,6 +146,8 @@ private: QString getClientDirectory() const; QString getClientExecutablePath() const; + bool shouldDownloadLauncher(); + QNetworkAccessManager _networkAccessManager; LatestBuilds _latestBuilds; QDir _launcherDirectory; diff --git a/launchers/qt/src/darwin/NSTask+NSTaskExecveAdditions.h b/launchers/qt/src/NSTask+NSTaskExecveAdditions.h similarity index 100% rename from launchers/qt/src/darwin/NSTask+NSTaskExecveAdditions.h rename to launchers/qt/src/NSTask+NSTaskExecveAdditions.h diff --git a/launchers/qt/src/darwin/NSTask+NSTaskExecveAdditions.m b/launchers/qt/src/NSTask+NSTaskExecveAdditions.m similarity index 100% rename from launchers/qt/src/darwin/NSTask+NSTaskExecveAdditions.m rename to launchers/qt/src/NSTask+NSTaskExecveAdditions.m diff --git a/launchers/qt/src/main.cpp b/launchers/qt/src/main.cpp index c848f13b9f..df5987dd62 100644 --- a/launchers/qt/src/main.cpp +++ b/launchers/qt/src/main.cpp @@ -7,6 +7,7 @@ #include "Helper.h" #ifdef Q_OS_WIN +#include "LauncherInstaller_windows.h" Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin); #elif defined(Q_OS_MACOS) Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin); @@ -26,8 +27,18 @@ bool hasSuffix(const std::string path, const std::string suffix) { return false; } +bool containsOption(int argc, char* argv[], const std::string& option) { + for (int index = 0; index < argc; index++) { + if (option.compare(argv[index]) == 0) { + return true; + } + } + return false; +} + int main(int argc, char *argv[]) { + //std::cout << "Launcher version: " << LAUNCHER_BUILD_VERSION; #ifdef Q_OS_MAC // auto updater if (argc == 3) { @@ -38,6 +49,13 @@ int main(int argc, char *argv[]) { std::cout << "not swapping launcher \n"; } } +#elif defined(Q_OS_WIN) + // try-install + + if (containsOption(argc, argv, "--restart")) { + LauncherInstaller launcherInstaller(argv[0]); + launcherInstaller.install(); + } #endif QString name { "High Fidelity" }; QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);