From 308483f4e71eb30e9955cede166e6d427418b9c2 Mon Sep 17 00:00:00 2001 From: danteruiz Date: Wed, 25 Sep 2019 18:15:15 -0700 Subject: [PATCH 1/6] working on file system links --- launchers/qt/CMakeLists.txt | 10 +++- launchers/qt/src/Helper.h | 8 +++ launchers/qt/src/Helper_windows.cpp | 51 +++++++++++++++++-- launchers/qt/src/Launcher.cpp | 1 - .../qt/src/LauncherInstaller_windows.cpp | 12 ++++- launchers/qt/src/LauncherState.cpp | 5 +- launchers/qt/src/main.cpp | 2 - 7 files changed, 76 insertions(+), 13 deletions(-) diff --git a/launchers/qt/CMakeLists.txt b/launchers/qt/CMakeLists.txt index 169240c647..c10d78de47 100644 --- a/launchers/qt/CMakeLists.txt +++ b/launchers/qt/CMakeLists.txt @@ -16,6 +16,10 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) include("cmake/init.cmake") include("cmake/macros/SetPackagingParameters.cmake") +if (WIN32) + set(CMAKE_MFC_FLAG 1) +endif() + function(set_from_env _RESULT_NAME _ENV_VAR_NAME _DEFAULT_VALUE) if (NOT DEFINED ${_RESULT_NAME}) @@ -119,6 +123,8 @@ foreach(plugin ${Qt5Gui_PLUGINS}) set(plugin_libs ${plugin_libs} ${_loc}) endforeach() +qt5_add_resources(EXAMPLE_RCC_SRC build/resources.qrc) + set(src_files src/main.cpp src/Launcher.h @@ -135,7 +141,7 @@ set(src_files src/Helper.cpp deps/miniz/miniz.h deps/miniz/miniz.cpp - ${RES_SOURCES} + #${RES_SOURCES} ) @@ -159,7 +165,7 @@ set(TARGET_NAME ${PROJECT_NAME}) set_packaging_parameters() if (WIN32) - add_executable(${PROJECT_NAME} ${src_files} build/resources.qrc) + add_executable(${PROJECT_NAME} ${src_files})#build/resources.qrc ${EXAMPLE_RCC_SRC}) elseif (APPLE) set_target_properties(${this_target} PROPERTIES MACOSX_BUNDLE_INFO_PLIST MacOSXBundleInfo.plist.in) diff --git a/launchers/qt/src/Helper.h b/launchers/qt/src/Helper.h index 7d1f54a949..975eb383d7 100644 --- a/launchers/qt/src/Helper.h +++ b/launchers/qt/src/Helper.h @@ -1,6 +1,10 @@ #include #include +#ifdef Q_OS_WIN +#include "Windows.h" +#endif + void launchClient(const QString& clientPath, const QString& homePath, const QString& defaultScriptOverride, const QString& displayName, const QString& contentCachePath, QString loginResponseToken = QString()); @@ -11,3 +15,7 @@ void swapLaunchers(const QString& oldLauncherPath = QString(), const QString& ne #ifdef Q_OS_MAC bool replaceDirectory(const QString& orginalDirectory, const QString& newDirectory); #endif + +#ifdef Q_OS_WIN +HRESULT createSymbolicLink(LPCSTR lpszPathObj, LPCSTR lpszPathLink, LPCSTR lpszDesc, LPCSTR lpszArgs); +#endif diff --git a/launchers/qt/src/Helper_windows.cpp b/launchers/qt/src/Helper_windows.cpp index cb3671f274..5295943a4e 100644 --- a/launchers/qt/src/Helper_windows.cpp +++ b/launchers/qt/src/Helper_windows.cpp @@ -1,7 +1,12 @@ #include "Helper.h" +#include "windows.h" +#include "winnls.h" +#include "shobjidl.h" +#include "objbase.h" +#include "objidl.h" +#include "shlguid.h" #include -#include void launchClient(const QString& clientPath, const QString& homePath, const QString& defaultScriptsPath, const QString& displayName, const QString& contentCachePath, QString loginResponseToken) { @@ -34,12 +39,12 @@ void launchClient(const QString& clientPath, const QString& homePath, const QStr 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 + nullptr, // Use parent's starting directory &si, // Pointer to STARTUPINFO structure &pi // Pointer to PROCESS_INFORMATION structure ); - // Close process and thread handles. + // Close process and thread handles. CloseHandle(pi.hProcess); CloseHandle(pi.hThread); @@ -68,3 +73,43 @@ void launchAutoUpdater(const QString& autoUpdaterPath) { &pi // Pointer to PROCESS_INFORMATION structure ); } + + +HRESULT createSymbolicLink(LPCSTR lpszPathObj, LPCSTR lpszPathLink, LPCSTR lpszDesc, LPCSTR lpszArgs) { + IShellLink* psl; + + // Get a pointer to the IShellLink interface. It is assumed that CoInitialize + // has already been called. + CoInitialize(NULL); + HRESULT hres = E_INVALIDARG; + hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); + if (SUCCEEDED(hres)) { + IPersistFile* ppf; + + // Set the path to the shortcut target and add the description. + psl->SetPath(lpszPathObj); + psl->SetDescription(lpszDesc); + psl->SetArguments(lpszArgs); + + // Query IShellLink for the IPersistFile interface, used for saving the + // shortcut in persistent storage. + hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf); + + if (SUCCEEDED(hres)) { + WCHAR wsz[MAX_PATH]; + + // Ensure that the string is Unicode. + MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1, wsz, MAX_PATH); + + // Add code here to check return value from MultiByteWideChar + // for success. + + // Save the link by calling IPersistFile::Save. + hres = ppf->Save(wsz, TRUE); + ppf->Release(); + } + psl->Release(); + } + CoUninitialize(); + return SUCCEEDED(hres); +} diff --git a/launchers/qt/src/Launcher.cpp b/launchers/qt/src/Launcher.cpp index 8ad9085cc8..2d5fd8dc21 100644 --- a/launchers/qt/src/Launcher.cpp +++ b/launchers/qt/src/Launcher.cpp @@ -9,7 +9,6 @@ #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 index 4a3f819c23..dc49c7d738 100644 --- a/launchers/qt/src/LauncherInstaller_windows.cpp +++ b/launchers/qt/src/LauncherInstaller_windows.cpp @@ -1,6 +1,7 @@ #include "LauncherInstaller_windows.h" +#include "Helper.h" -#include +#include #include #include @@ -37,6 +38,15 @@ void LauncherInstaller::install() { } else { qDebug() << "not successful"; } + + qDebug() << "LauncherInstaller: create uninstall link"; + QString uninstallLinkPath = _launcherInstallDir.absolutePath() + "/Uninstall HQ.link"; + if (QFile::exists(uninstallLinkPath)) { + QFile::remove(uninstallLinkPath); + } + + createSymbolicLink((LPCSTR)oldLauncherPath.toStdString().c_str(), (LPCSTR)uninstallLinkPath.toStdString().c_str(), + (LPCSTR)("Click to Uninstall HQ"), (LPCSTR)("--uninstall")); } } diff --git a/launchers/qt/src/LauncherState.cpp b/launchers/qt/src/LauncherState.cpp index 1a8023e236..f9ada2bc41 100644 --- a/launchers/qt/src/LauncherState.cpp +++ b/launchers/qt/src/LauncherState.cpp @@ -4,9 +4,6 @@ #include "Unzipper.h" #include "Helper.h" -#ifdef Q_OS_WIN -#include -#endif #include #include @@ -70,7 +67,7 @@ bool LatestBuilds::getBuild(QString tag, Build* outBuild) { } static const std::array QML_FILE_FOR_UI_STATE = - { { "SplashScreen.qml", "qml/HFBase/CreateAccountBase.qml", "DisplayName.qml", + { { "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) { diff --git a/launchers/qt/src/main.cpp b/launchers/qt/src/main.cpp index df5987dd62..3c810434e7 100644 --- a/launchers/qt/src/main.cpp +++ b/launchers/qt/src/main.cpp @@ -37,7 +37,6 @@ bool containsOption(int argc, char* argv[], const std::string& option) { } int main(int argc, char *argv[]) { - //std::cout << "Launcher version: " << LAUNCHER_BUILD_VERSION; #ifdef Q_OS_MAC // auto updater @@ -60,7 +59,6 @@ int main(int argc, char *argv[]) { QString name { "High Fidelity" }; QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QCoreApplication::setOrganizationName(name); - Launcher launcher(argc, argv); return launcher.exec(); From 1d50856931823ac568dd95b3f51dfc47ee2f3e91 Mon Sep 17 00:00:00 2001 From: dante ruiz Date: Thu, 26 Sep 2019 10:50:32 -0700 Subject: [PATCH 2/6] update qt build --- launchers/qt/CMakeLists.txt | 4 ++-- launchers/qt/src/Helper_darwin.mm | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/launchers/qt/CMakeLists.txt b/launchers/qt/CMakeLists.txt index c10d78de47..831895c3ab 100644 --- a/launchers/qt/CMakeLists.txt +++ b/launchers/qt/CMakeLists.txt @@ -68,8 +68,8 @@ endif () if (APPLE) ExternalProject_Add( qtlite - URL "https://dantescalves.com/launcher/qt-lite-clang-8.1.0.zip" - URL_HASH MD5=f8462bfcd54e6b05ef888f8b197149c2 + URL "https://dantescalves.com/launcher/qt-lite-5.9.9-mac.zip" + URL_HASH MD5=0cd78d40e5f539a7e314cf99b6cae0d0 CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" diff --git a/launchers/qt/src/Helper_darwin.mm b/launchers/qt/src/Helper_darwin.mm index 47bdcb2814..417abbb647 100644 --- a/launchers/qt/src/Helper_darwin.mm +++ b/launchers/qt/src/Helper_darwin.mm @@ -1,4 +1,4 @@ -#include "../Helper.h" +#include "Helper.h" #import "NSTask+NSTaskExecveAdditions.h" From 836e23f5cf60391aa7dccbfc266c597debbd81bc Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 26 Sep 2019 16:32:25 -0700 Subject: [PATCH 3/6] override defualt latest build url and add commandlineOption --- launchers/qt/CMakeLists.txt | 2 ++ launchers/qt/resources/qml/HFBase/Error.qml | 4 +++ launchers/qt/resources/qml/root.qml | 2 +- launchers/qt/src/CommandlineOptions.cpp | 30 ++++++++++++++++ launchers/qt/src/CommandlineOptions.h | 16 +++++++++ launchers/qt/src/Helper_darwin.mm | 2 +- launchers/qt/src/Launcher.cpp | 1 - launchers/qt/src/LauncherState.cpp | 39 ++++++++++----------- launchers/qt/src/LauncherState.h | 2 ++ launchers/qt/src/main.cpp | 23 ++++-------- 10 files changed, 81 insertions(+), 40 deletions(-) create mode 100644 launchers/qt/src/CommandlineOptions.cpp create mode 100644 launchers/qt/src/CommandlineOptions.h diff --git a/launchers/qt/CMakeLists.txt b/launchers/qt/CMakeLists.txt index 831895c3ab..53b1f54796 100644 --- a/launchers/qt/CMakeLists.txt +++ b/launchers/qt/CMakeLists.txt @@ -139,6 +139,8 @@ set(src_files src/Unzipper.cpp src/Helper.h src/Helper.cpp + src/CommandlineOptions.h + src/CommandlineOptions.cpp deps/miniz/miniz.h deps/miniz/miniz.cpp #${RES_SOURCES} diff --git a/launchers/qt/resources/qml/HFBase/Error.qml b/launchers/qt/resources/qml/HFBase/Error.qml index d05ef01413..f488a3e9bf 100644 --- a/launchers/qt/resources/qml/HFBase/Error.qml +++ b/launchers/qt/resources/qml/HFBase/Error.qml @@ -78,6 +78,10 @@ Item { topMargin: 15 horizontalCenter: description.horizontalCenter } + + onClicked: { + LauncherState.restart(); + } } diff --git a/launchers/qt/resources/qml/root.qml b/launchers/qt/resources/qml/root.qml index bfd704fa50..3c755c2a6b 100644 --- a/launchers/qt/resources/qml/root.qml +++ b/launchers/qt/resources/qml/root.qml @@ -15,7 +15,7 @@ Item { } Component.onCompleted: { - loader.source = LauncherState.getCurrentUISource(); + loader.source = "./SplashScreen.qml"; LauncherState.updateSourceUrl.connect(function(url) { loader.source = url; }); diff --git a/launchers/qt/src/CommandlineOptions.cpp b/launchers/qt/src/CommandlineOptions.cpp new file mode 100644 index 0000000000..162d3414f3 --- /dev/null +++ b/launchers/qt/src/CommandlineOptions.cpp @@ -0,0 +1,30 @@ +#include "CommandlineOptions.h" + +#include +#include + +bool isCommandlineOption(const std::string& option) { + if (option.rfind("--", 0) == 0 && option.at(2) != '-') { + return true; + } + return false; +} +bool CommandlineOptions::contains(const std::string& option) { + auto iter = std::find(_commandlineOptions.begin(), _commandlineOptions.end(), option); + return (iter != _commandlineOptions.end()); +} + +void CommandlineOptions::parse(const int argc, char** argv) { + for (int index = 1; index < argc; index++) { + std::string option = argv[index]; + if (isCommandlineOption(option)) { + std::cout << "adding commandline option: " << option << "\n"; + _commandlineOptions.push_back(option); + } + } +} + +CommandlineOptions* CommandlineOptions::getInstance() { + static CommandlineOptions commandlineOptions; + return &commandlineOptions; +} diff --git a/launchers/qt/src/CommandlineOptions.h b/launchers/qt/src/CommandlineOptions.h new file mode 100644 index 0000000000..4a34bd1337 --- /dev/null +++ b/launchers/qt/src/CommandlineOptions.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include + +class CommandlineOptions { +public: + CommandlineOptions() = default; + ~CommandlineOptions() = default; + + void parse(const int argc, char** argv); + bool contains(const std::string& option); + static CommandlineOptions* getInstance(); +private: + std::vector _commandlineOptions; +}; diff --git a/launchers/qt/src/Helper_darwin.mm b/launchers/qt/src/Helper_darwin.mm index 417abbb647..5ffde89caf 100644 --- a/launchers/qt/src/Helper_darwin.mm +++ b/launchers/qt/src/Helper_darwin.mm @@ -7,7 +7,7 @@ #include void launchClient(const QString& clientPath, const QString& homePath, const QString& defaultScriptOverride, - const QString& displayName, const QString& contentCachePath, QString& loginTokenResponse) { + const QString& displayName, const QString& contentCachePath, QString loginTokenResponse) { NSString* homeBookmark = [[NSString stringWithFormat:@"hqhome="] stringByAppendingString:homePath.toNSString()]; NSArray* arguments; diff --git a/launchers/qt/src/Launcher.cpp b/launchers/qt/src/Launcher.cpp index 2d5fd8dc21..96da608f7d 100644 --- a/launchers/qt/src/Launcher.cpp +++ b/launchers/qt/src/Launcher.cpp @@ -13,7 +13,6 @@ Launcher::Launcher(int& argc, char**argv) : QGuiApplication(argc, argv) { qDebug() << "resources.rcc path: " << resourceBinaryLocation; QResource::registerResource(resourceBinaryLocation); _launcherState = std::make_shared(); - //_launcherState->setUIState(LauncherState::SPLASH_SCREEN); _launcherWindow = std::make_unique(); _launcherWindow->rootContext()->setContextProperty("LauncherState", _launcherState.get()); _launcherWindow->rootContext()->setContextProperty("PathUtils", new PathUtils()); diff --git a/launchers/qt/src/LauncherState.cpp b/launchers/qt/src/LauncherState.cpp index f9ada2bc41..c6345522b2 100644 --- a/launchers/qt/src/LauncherState.cpp +++ b/launchers/qt/src/LauncherState.cpp @@ -151,12 +151,25 @@ void LauncherState::requestBuilds() { setApplicationState(ApplicationState::RequestingBuilds); // TODO Show splash screen until this request is complete - auto request = new QNetworkRequest(QUrl("https://thunder.highfidelity.com/builds/api/tags/latest/?format=json")); + + QString latestBuildRequestUrl { "https://thunder.highfidelity.com/builds/api/tags/latest/?format=json" }; + QProcessEnvironment processEnvironment =QProcessEnvironment::systemEnvironment(); + + if (processEnvironment.contains("HQ_LAUNCHER_BUILDS_URL")) { + latestBuildRequestUrl = processEnvironment.value("HQ_LAUNCHER_BUILDS_URL"); + } + + auto request = new QNetworkRequest(QUrl(latestBuildRequestUrl)); auto reply = _networkAccessManager.get(*request); QObject::connect(reply, &QNetworkReply::finished, this, &LauncherState::receivedBuildsReply); } +void LauncherState::restart() { + setApplicationState(ApplicationState::Init); + requestBuilds(); +} + void LauncherState::receivedBuildsReply() { auto reply = static_cast(sender()); @@ -219,7 +232,7 @@ void LauncherState::receivedBuildsReply() { } if (shouldDownloadLauncher()) { - downloadLauncher(); + //downloadLauncher(); } getCurrentClientVersion(); } @@ -239,27 +252,12 @@ void LauncherState::getCurrentClientVersion() { //connect(&client, &QProcess::errorOccurred, &loop, &QEventLoop::exit); connect(&client, QOverload::of(&QProcess::finished), &loop, &QEventLoop::exit); - /* - connect(&client, QOverload::of(&QProcess::finished), [&]() { - qDebug() << "Finished"; - }); - connect(&client, &QProcess::errorOccurred, [&](QProcess::ProcessError err) { - qDebug() << "Error occurred" << err << client.error(); - }); - connect(&client, &QProcess::started, [&]() { - qDebug() << "Started"; - }); - connect(&client, &QProcess::stateChanged, [&]() { - qDebug() << "State changed " << client.state(); - }); - */ + connect(&client, &QProcess::errorOccurred, &loop, &QEventLoop::exit, Qt::QueuedConnection); - //qDebug() << "Starting client"; client.start(getClientExecutablePath(), { "--version" }); - //qDebug() << "Started" << client.error(); if (client.state() != QProcess::NotRunning) { - //qDebug() << "Starting loop"; + loop.exec(); } else { qDebug() << "Not waiting for client, there was an error starting it: " << client.error(); @@ -389,12 +387,13 @@ void LauncherState::receivedSettingsReply() { } _homeLocation = "hifi://hq"; + _contentCacheURL = "http://orgs.highfidelity.com/host-content-cache/" + QUrl(_homeLocation).host() + ".zip"; if (root["data"].toObject().contains("home_location")) { auto homeLocation = root["data"].toObject()["home_location"]; if (homeLocation.isString()) { _homeLocation = homeLocation.toString(); auto host = QUrl(_homeLocation).host(); - _contentCacheURL = "http://orgs.highfidelity.com/host-content-cache/" + host + ".zip"; + //_contentCacheURL = "http://orgs.highfidelity.com/host-content-cache/" + host + ".zip"; qDebug() << "Home location is: " << _homeLocation; qDebug() << "Content cache url is: " << _contentCacheURL; } diff --git a/launchers/qt/src/LauncherState.h b/launchers/qt/src/LauncherState.h index f3a3c4a313..b66d9e90e3 100644 --- a/launchers/qt/src/LauncherState.h +++ b/launchers/qt/src/LauncherState.h @@ -110,6 +110,8 @@ public: void requestSettings(); Q_INVOKABLE void receivedSettingsReply(); + Q_INVOKABLE void restart(); + // Launcher void downloadLauncher(); void installLauncher(); diff --git a/launchers/qt/src/main.cpp b/launchers/qt/src/main.cpp index 3c810434e7..ed5cbe8138 100644 --- a/launchers/qt/src/main.cpp +++ b/launchers/qt/src/main.cpp @@ -2,6 +2,7 @@ #include "LauncherWindow.h" #include "Launcher.h" +#include "CommandlineOptions.h" #include #include #include "Helper.h" @@ -27,31 +28,19 @@ 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) { if (hasSuffix(argv[1], "app") && hasSuffix(argv[2], "app")) { - std::cout << "swapping launcher \n"; swapLaunchers(argv[1], argv[2]); - } else { - std::cout << "not swapping launcher \n"; } } -#elif defined(Q_OS_WIN) - // try-install - - if (containsOption(argc, argv, "--restart")) { +#endif + CommandlineOptions* options = CommandlineOptions::getInstance(); + options->parse(argc, argv); +#ifdef Q_OS_WIN + if (options->contains("--restart")) { LauncherInstaller launcherInstaller(argv[0]); launcherInstaller.install(); } From e8205728ce85c9d06c2c69cc2209dd101fe3f10b Mon Sep 17 00:00:00 2001 From: danteruiz Date: Fri, 27 Sep 2019 15:31:44 -0700 Subject: [PATCH 4/6] install and uninstall features --- launchers/qt/src/Helper.h | 2 +- .../qt/src/LauncherInstaller_windows.cpp | 53 ++++++++++++++++++- launchers/qt/src/LauncherInstaller_windows.h | 6 ++- launchers/qt/src/main.cpp | 7 ++- 4 files changed, 62 insertions(+), 6 deletions(-) diff --git a/launchers/qt/src/Helper.h b/launchers/qt/src/Helper.h index 975eb383d7..d26cacfa5c 100644 --- a/launchers/qt/src/Helper.h +++ b/launchers/qt/src/Helper.h @@ -17,5 +17,5 @@ bool replaceDirectory(const QString& orginalDirectory, const QString& newDirecto #endif #ifdef Q_OS_WIN -HRESULT createSymbolicLink(LPCSTR lpszPathObj, LPCSTR lpszPathLink, LPCSTR lpszDesc, LPCSTR lpszArgs); +HRESULT createSymbolicLink(LPCSTR lpszPathObj, LPCSTR lpszPathLink, LPCSTR lpszDesc, LPCSTR lpszArgs = (LPCSTR)""); #endif diff --git a/launchers/qt/src/LauncherInstaller_windows.cpp b/launchers/qt/src/LauncherInstaller_windows.cpp index dc49c7d738..ea35e86c64 100644 --- a/launchers/qt/src/LauncherInstaller_windows.cpp +++ b/launchers/qt/src/LauncherInstaller_windows.cpp @@ -10,8 +10,11 @@ LauncherInstaller::LauncherInstaller(const QString& applicationFilePath) { _launcherInstallDir = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/HQ"; + _launcherApplicationsDir = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/HQ"; qDebug() << "Launcher install dir: " << _launcherInstallDir.absolutePath(); + qDebug() << "Launcher Application dir: " << _launcherApplicationsDir.absolutePath(); _launcherInstallDir.mkpath(_launcherInstallDir.absolutePath()); + _launcherApplicationsDir.mkpath(_launcherApplicationsDir.absolutePath()); QFileInfo fileInfo(applicationFilePath); _launcherRunningFilePath = fileInfo.absoluteFilePath(); _launcherRunningDirPath = fileInfo.absoluteDir().absolutePath(); @@ -24,6 +27,7 @@ bool LauncherInstaller::runningOutsideOfInstallDir() { } void LauncherInstaller::install() { + //qDebug() << "Is install dir empty: " << _launcherInstallDir.isEmpty(); if (runningOutsideOfInstallDir()) { qDebug() << "Installing HQ Launcher...."; QString oldLauncherPath = _launcherInstallDir.absolutePath() + "/HQ Launcher.exe"; @@ -40,14 +44,59 @@ void LauncherInstaller::install() { } qDebug() << "LauncherInstaller: create uninstall link"; - QString uninstallLinkPath = _launcherInstallDir.absolutePath() + "/Uninstall HQ.link"; + QString uninstallLinkPath = _launcherInstallDir.absolutePath() + "/Uninstall HQ.lnk"; if (QFile::exists(uninstallLinkPath)) { QFile::remove(uninstallLinkPath); } + + + QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); + QString applicationPath = _launcherApplicationsDir.absolutePath(); + + QString appStartLinkPath = applicationPath + "/HQ.lnk"; + QString uninstallAppStartLinkPath = applicationPath + "/Uninstall HQ.lnk"; + QString desktopAppLinkPath = desktopPath + "/HQ.lnk"; + + createSymbolicLink((LPCSTR)oldLauncherPath.toStdString().c_str(), (LPCSTR)uninstallLinkPath.toStdString().c_str(), (LPCSTR)("Click to Uninstall HQ"), (LPCSTR)("--uninstall")); + + createSymbolicLink((LPCSTR)oldLauncherPath.toStdString().c_str(), (LPCSTR)uninstallAppStartLinkPath.toStdString().c_str(), + (LPCSTR)("Click to Uninstall HQ"), (LPCSTR)("--uninstall")); + + createSymbolicLink((LPCSTR)oldLauncherPath.toStdString().c_str(), (LPCSTR)desktopAppLinkPath.toStdString().c_str(), + (LPCSTR)("Click to Setup and Launch HQ")); + + createSymbolicLink((LPCSTR)oldLauncherPath.toStdString().c_str(), (LPCSTR)appStartLinkPath.toStdString().c_str(), + (LPCSTR)("Click to Setup and Launch HQ")); + } else { + qDebug() << "FAILED!!!!!!!"; } } -void LauncherInstaller::uninstall() {} +void LauncherInstaller::uninstall() { + qDebug() << "Uninstall Launcher"; + QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); + QString applicationPath = _launcherApplicationsDir.absolutePath(); + + QString uninstallLinkPath = _launcherInstallDir.absolutePath() + "/Uninstall HQ.lnk"; + if (QFile::exists(uninstallLinkPath)) { + QFile::remove(uninstallLinkPath); + } + + QString appStartLinkPath = applicationPath + "/HQ.lnk"; + if (QFile::exists(appStartLinkPath)) { + QFile::remove(appStartLinkPath); + } + + QString uninstallAppStartLinkPath = applicationPath + "/Uninstall HQ.lnk"; + if (QFile::exists(uninstallAppStartLinkPath)) { + QFile::remove(uninstallAppStartLinkPath); + } + + QString desktopAppLinkPath = desktopPath + "/HQ.lnk"; + if (QFile::exists(desktopAppLinkPath)) { + QFile::remove(desktopAppLinkPath); + } +} diff --git a/launchers/qt/src/LauncherInstaller_windows.h b/launchers/qt/src/LauncherInstaller_windows.h index 1aa10ce876..8791f9395f 100644 --- a/launchers/qt/src/LauncherInstaller_windows.h +++ b/launchers/qt/src/LauncherInstaller_windows.h @@ -8,9 +8,13 @@ public: void install(); void uninstall(); -private: bool runningOutsideOfInstallDir(); +private: + void createShortcuts(); + void deleteShortcuts(); + QDir _launcherInstallDir; + QDir _launcherApplicationsDir; QString _launcherRunningFilePath; QString _launcherRunningDirPath; }; diff --git a/launchers/qt/src/main.cpp b/launchers/qt/src/main.cpp index ed5cbe8138..6b2bd39fde 100644 --- a/launchers/qt/src/main.cpp +++ b/launchers/qt/src/main.cpp @@ -40,9 +40,12 @@ int main(int argc, char *argv[]) { CommandlineOptions* options = CommandlineOptions::getInstance(); options->parse(argc, argv); #ifdef Q_OS_WIN - if (options->contains("--restart")) { - LauncherInstaller launcherInstaller(argv[0]); + LauncherInstaller launcherInstaller(argv[0]); + if (options->contains("--restart") || launcherInstaller.runningOutsideOfInstallDir()) { launcherInstaller.install(); + } else if (options->contains("--uninstall")) { + launcherInstaller.uninstall(); + return 0; } #endif QString name { "High Fidelity" }; From d5f042c3619674095221459cbacbdefa1cadd56a Mon Sep 17 00:00:00 2001 From: dante ruiz Date: Fri, 27 Sep 2019 16:59:04 -0700 Subject: [PATCH 5/6] static link resources --- launchers/qt/CMakeLists.txt | 28 +++++++++------------------- launchers/qt/src/Launcher.cpp | 3 --- launchers/qt/src/LauncherState.h | 2 +- launchers/qt/src/PathUtils.cpp | 4 ++-- launchers/qt/src/PathUtils.h | 4 +++- launchers/qt/src/main.cpp | 1 + 6 files changed, 16 insertions(+), 26 deletions(-) diff --git a/launchers/qt/CMakeLists.txt b/launchers/qt/CMakeLists.txt index 53b1f54796..d54189137c 100644 --- a/launchers/qt/CMakeLists.txt +++ b/launchers/qt/CMakeLists.txt @@ -123,8 +123,6 @@ foreach(plugin ${Qt5Gui_PLUGINS}) set(plugin_libs ${plugin_libs} ${_loc}) endforeach() -qt5_add_resources(EXAMPLE_RCC_SRC build/resources.qrc) - set(src_files src/main.cpp src/Launcher.h @@ -143,7 +141,6 @@ set(src_files src/CommandlineOptions.cpp deps/miniz/miniz.h deps/miniz/miniz.cpp - #${RES_SOURCES} ) @@ -167,13 +164,13 @@ set(TARGET_NAME ${PROJECT_NAME}) set_packaging_parameters() if (WIN32) - add_executable(${PROJECT_NAME} ${src_files})#build/resources.qrc ${EXAMPLE_RCC_SRC}) + add_executable(${PROJECT_NAME} ${src_files} ${RES_SOURCES}) elseif (APPLE) set_target_properties(${this_target} PROPERTIES MACOSX_BUNDLE_INFO_PLIST MacOSXBundleInfo.plist.in) set(MACOSX_BUNDLE_ICON_FILE "interface.icns") - add_executable(${PROJECT_NAME} MACOSX_BUNDLE ${src_files}) + add_executable(${PROJECT_NAME} MACOSX_BUNDLE ${src_files} ${RES_SOURCES}) set_target_properties(${PROJECT_NAME} PROPERTIES XCODE_ATTRIBUTE_ENABLE_BITCODE "NO") endif() @@ -222,21 +219,14 @@ if (APPLE) ${OPENSSL_INCLUDE_DIR}) endif() -set(INTERFACE_EXEC_DIR "$") -set(RESOURCES_DEV_DIR "${INTERFACE_EXEC_DIR}/resources") -add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD - COMMAND "${CMAKE_COMMAND}" -E copy_if_different - "${RESOURCES_RCC}" - "${INTERFACE_EXEC_DIR}") - -if (LAUNCHER_SOURCE_TREE_RESOURCES) - target_compile_definitions(${PROJECT_NAME} PRIVATE RESOURCE_PREFIX_URL="${CMAKE_CURRENT_SOURCE_DIR}/resources/") - message("Use source tree resources path: file://${CMAKE_CURRENT_SOURCE_DIR}/resources/") -else() - target_compile_definitions(${PROJECT_NAME} PRIVATE RESOURCE_PREFIX_URL="qrc:/") - message("Use resource.rcc path: qrc:/") -endif() + if (LAUNCHER_SOURCE_TREE_RESOURCES) + target_compile_definitions(${PROJECT_NAME} PRIVATE RESOURCE_PREFIX_URL="${CMAKE_CURRENT_SOURCE_DIR}/resources/") + message("Use source tree resources path: file://${CMAKE_CURRENT_SOURCE_DIR}/resources/") + else() + target_compile_definitions(${PROJECT_NAME} PRIVATE RESOURCE_PREFIX_URL="qrc:/") + message("Use resource.rcc path: qrc:/") + endif() target_compile_definitions(${PROJECT_NAME} PRIVATE LAUNCHER_BUILD_VERSION="${BUILD_VERSION}") diff --git a/launchers/qt/src/Launcher.cpp b/launchers/qt/src/Launcher.cpp index 96da608f7d..0b51328aef 100644 --- a/launchers/qt/src/Launcher.cpp +++ b/launchers/qt/src/Launcher.cpp @@ -9,9 +9,6 @@ #include "PathUtils.h" Launcher::Launcher(int& argc, char**argv) : QGuiApplication(argc, argv) { - QString resourceBinaryLocation = QGuiApplication::applicationDirPath() + "/resources.rcc"; - qDebug() << "resources.rcc path: " << resourceBinaryLocation; - QResource::registerResource(resourceBinaryLocation); _launcherState = std::make_shared(); _launcherWindow = std::make_unique(); _launcherWindow->rootContext()->setContextProperty("LauncherState", _launcherState.get()); diff --git a/launchers/qt/src/LauncherState.h b/launchers/qt/src/LauncherState.h index b66d9e90e3..b96440c827 100644 --- a/launchers/qt/src/LauncherState.h +++ b/launchers/qt/src/LauncherState.h @@ -130,7 +130,7 @@ public: Q_INVOKABLE float getDownloadProgress() const { return _downloadProgress; } signals: - void updateSourceUrl(QString sourceUrl); + void updateSourceUrl(QUrl sourceUrl); void uiStateChanged(); void applicationStateChanged(); void downloadProgressChanged(); diff --git a/launchers/qt/src/PathUtils.cpp b/launchers/qt/src/PathUtils.cpp index ae02585788..542e268308 100644 --- a/launchers/qt/src/PathUtils.cpp +++ b/launchers/qt/src/PathUtils.cpp @@ -2,6 +2,6 @@ #include -QString PathUtils::resourcePath(const QString& source) { - return QString(RESOURCE_PREFIX_URL + source); +QUrl PathUtils::resourcePath(const QString& source) { + return QUrl(RESOURCE_PREFIX_URL + source); } diff --git a/launchers/qt/src/PathUtils.h b/launchers/qt/src/PathUtils.h index 29d9b609d6..3bfddd624c 100644 --- a/launchers/qt/src/PathUtils.h +++ b/launchers/qt/src/PathUtils.h @@ -2,10 +2,12 @@ #include #include +#include +#include class PathUtils : public QObject { Q_OBJECT public: PathUtils() = default; ~PathUtils() = default; - Q_INVOKABLE static QString resourcePath(const QString& source); + Q_INVOKABLE static QUrl resourcePath(const QString& source); }; diff --git a/launchers/qt/src/main.cpp b/launchers/qt/src/main.cpp index 6b2bd39fde..a1c7ab61ca 100644 --- a/launchers/qt/src/main.cpp +++ b/launchers/qt/src/main.cpp @@ -29,6 +29,7 @@ bool hasSuffix(const std::string path, const std::string suffix) { } int main(int argc, char *argv[]) { + Q_INIT_RESOURCE(resources); #ifdef Q_OS_MAC // auto updater if (argc == 3) { From 13e8dc036c2898cf5adfb088764f2c0f9996ded9 Mon Sep 17 00:00:00 2001 From: dante ruiz Date: Mon, 30 Sep 2019 14:24:14 -0700 Subject: [PATCH 6/6] mac close interface and launcher and fix compile warnings --- launchers/qt/CMakeLists.txt | 1 + launchers/qt/src/Helper.h | 3 ++ launchers/qt/src/Helper_darwin.mm | 40 +++++++++++++++++++ launchers/qt/src/LauncherState.h | 6 +-- .../qt/src/NSTask+NSTaskExecveAdditions.m | 8 ++-- launchers/qt/src/Unzipper.cpp | 2 +- launchers/qt/src/main.cpp | 5 +++ 7 files changed, 56 insertions(+), 9 deletions(-) diff --git a/launchers/qt/CMakeLists.txt b/launchers/qt/CMakeLists.txt index d54189137c..57f900140c 100644 --- a/launchers/qt/CMakeLists.txt +++ b/launchers/qt/CMakeLists.txt @@ -35,6 +35,7 @@ include(ExternalProject) if (APPLE) set(CMAKE_EXE_LINKER_FLAGS "-framework Cocoa -framework CoreServices -framework Carbon -framework IOKit -framework Security -framework SystemConfiguration") + add_compile_options(-W -Wall -Wextra -Wpedantic) endif() if (WIN32) diff --git a/launchers/qt/src/Helper.h b/launchers/qt/src/Helper.h index d26cacfa5c..65f68ec41d 100644 --- a/launchers/qt/src/Helper.h +++ b/launchers/qt/src/Helper.h @@ -14,6 +14,9 @@ void swapLaunchers(const QString& oldLauncherPath = QString(), const QString& ne #ifdef Q_OS_MAC bool replaceDirectory(const QString& orginalDirectory, const QString& newDirectory); +void closeInterfaceIfRunning(); +void waitForInterfaceToClose(); +bool isLauncherAlreadyRunning(); #endif #ifdef Q_OS_WIN diff --git a/launchers/qt/src/Helper_darwin.mm b/launchers/qt/src/Helper_darwin.mm index 5ffde89caf..28b35193ba 100644 --- a/launchers/qt/src/Helper_darwin.mm +++ b/launchers/qt/src/Helper_darwin.mm @@ -70,3 +70,43 @@ bool replaceDirectory(const QString& orginalDirectory, const QString& newDirecto return (bool) [fileManager replaceItemAtURL:[UpdaterHelper NSStringToNSURL:orginalDirectory.toNSString()] withItemAtURL:[UpdaterHelper NSStringToNSURL:newDirectory.toNSString()] backupItemName:nil options:NSFileManagerItemReplacementUsingNewMetadataOnly resultingItemURL:&destinationUrl error:nil]; } + + +void waitForInterfaceToClose() { + bool interfaceRunning = true; + + while (interfaceRunning) { + interfaceRunning = false; + NSWorkspace* workspace = [NSWorkspace sharedWorkspace]; + NSArray* apps = [workspace runningApplications]; + for (NSRunningApplication* app in apps) { + if ([[app bundleIdentifier] isEqualToString:@"com.highfidelity.interface"] || + [[app bundleIdentifier] isEqualToString:@"com.highfidelity.interface-pr"]) { + interfaceRunning = true; + break; + } + } + } +} + +bool isLauncherAlreadyRunning() { + NSArray* apps = [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.highfidelity.launcher"]; + NSLog(@"Count: %lu", [apps count]); + if ([apps count] > 1) { + NSLog(@"launcher is already running"); + return true; + } + + return false; +} + +void closeInterfaceIfRunning() { + NSWorkspace* workspace = [NSWorkspace sharedWorkspace]; + NSArray* apps = [workspace runningApplications]; + for (NSRunningApplication* app in apps) { + if ([[app bundleIdentifier] isEqualToString:@"com.highfidelity.interface"] || + [[app bundleIdentifier] isEqualToString:@"com.highfidelity.interface-pr"]) { + [app terminate]; + } + } +} diff --git a/launchers/qt/src/LauncherState.h b/launchers/qt/src/LauncherState.h index b96440c827..51e0399c1e 100644 --- a/launchers/qt/src/LauncherState.h +++ b/launchers/qt/src/LauncherState.h @@ -31,9 +31,9 @@ struct LoginResponse { class LauncherState : public QObject { Q_OBJECT - Q_PROPERTY(UIState uiState READ getUIState NOTIFY uiStateChanged); - Q_PROPERTY(ApplicationState applicationState READ getApplicationState NOTIFY applicationStateChanged); - Q_PROPERTY(float downloadProgress READ getDownloadProgress NOTIFY downloadProgressChanged); + Q_PROPERTY(UIState uiState READ getUIState NOTIFY uiStateChanged) + Q_PROPERTY(ApplicationState applicationState READ getApplicationState NOTIFY applicationStateChanged) + Q_PROPERTY(float downloadProgress READ getDownloadProgress NOTIFY downloadProgressChanged) public: LauncherState(); diff --git a/launchers/qt/src/NSTask+NSTaskExecveAdditions.m b/launchers/qt/src/NSTask+NSTaskExecveAdditions.m index 6cdf669247..a216b24e95 100644 --- a/launchers/qt/src/NSTask+NSTaskExecveAdditions.m +++ b/launchers/qt/src/NSTask+NSTaskExecveAdditions.m @@ -15,7 +15,7 @@ toCArray(NSArray *array) @throw exception; } char *str; - for (int i = 0; i < [array count]; i++) { + for (NSUInteger i = 0; i < [array count]; i++) { str = (char *) [array[i] UTF8String]; if (str == NULL) { NSException *exception = [NSException @@ -25,7 +25,7 @@ toCArray(NSArray *array) @throw exception; } if (asprintf(&cArray[i], "%s", str) == -1) { - for (int j = 0; j < i; j++) { + for (NSUInteger j = 0; j < i; j++) { free(cArray[j]); } free(cArray); @@ -54,13 +54,11 @@ toCArray(NSArray *array) char** envp = toCArray(env); // `execve` replaces the current process with `path`. // It will only return if it fails to replace the current process. - NSLog(@"------------>"); chdir(dirname(args[0])); execve(args[0], (char * const *)args, envp); - NSLog(@"----------- FAILED "); // If we're here `execve` failed. :( - for (int i = 0; i < [[self arguments] count]; i++) { + for (NSUInteger i = 0; i < [[self arguments] count]; i++) { free((void *) args[i]); } free((void *) args); diff --git a/launchers/qt/src/Unzipper.cpp b/launchers/qt/src/Unzipper.cpp index 5d08d3b25a..54a81f272e 100644 --- a/launchers/qt/src/Unzipper.cpp +++ b/launchers/qt/src/Unzipper.cpp @@ -49,7 +49,7 @@ void Unzipper::run() { uint64_t totalSize = 0; uint64_t totalCompressedSize = 0; - bool _shouldFail = false; + //bool _shouldFail = false; for (int i = 0; i < fileCount; i++) { if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) continue; diff --git a/launchers/qt/src/main.cpp b/launchers/qt/src/main.cpp index a1c7ab61ca..db69bfafe3 100644 --- a/launchers/qt/src/main.cpp +++ b/launchers/qt/src/main.cpp @@ -31,6 +31,11 @@ bool hasSuffix(const std::string path, const std::string suffix) { int main(int argc, char *argv[]) { Q_INIT_RESOURCE(resources); #ifdef Q_OS_MAC + if (isLauncherAlreadyRunning()) { + return 0; + } + closeInterfaceIfRunning(); + // waitForInterfaceToClose(); // auto updater if (argc == 3) { if (hasSuffix(argv[1], "app") && hasSuffix(argv[2], "app")) {