diff --git a/launchers/qt/CMakeLists.txt b/launchers/qt/CMakeLists.txt index 2cd6ff5456..085c1309ef 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}) @@ -31,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) @@ -64,8 +69,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 "" @@ -139,9 +144,10 @@ 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} ) @@ -165,13 +171,13 @@ set(TARGET_NAME ${PROJECT_NAME}) set_packaging_parameters() if (WIN32) - add_executable(${PROJECT_NAME} ${src_files} ${CMAKE_CURRENT_BINARY_DIR}/resources.qrc) + 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() @@ -220,21 +226,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/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.h b/launchers/qt/src/Helper.h index a0b4eb55fe..7fb0cf339b 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 + //#define USE_STAGING #ifdef USE_STAGING @@ -18,6 +22,13 @@ 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 +HRESULT createSymbolicLink(LPCSTR lpszPathObj, LPCSTR lpszPathLink, LPCSTR lpszDesc, LPCSTR lpszArgs = (LPCSTR)""); #endif QString getHTTPUserAgent(); diff --git a/launchers/qt/src/Helper_darwin.mm b/launchers/qt/src/Helper_darwin.mm index 47bdcb2814..28b35193ba 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" @@ -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; @@ -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/Helper_windows.cpp b/launchers/qt/src/Helper_windows.cpp index bc5185d9f6..69c5f59bfc 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..0b51328aef 100644 --- a/launchers/qt/src/Launcher.cpp +++ b/launchers/qt/src/Launcher.cpp @@ -9,12 +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); _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/LauncherInstaller_windows.cpp b/launchers/qt/src/LauncherInstaller_windows.cpp index 4a3f819c23..ea35e86c64 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 @@ -9,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(); @@ -23,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"; @@ -37,7 +42,61 @@ void LauncherInstaller::install() { } else { qDebug() << "not successful"; } + + qDebug() << "LauncherInstaller: create uninstall 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/LauncherState.cpp b/launchers/qt/src/LauncherState.cpp index 3901a5c4ab..976dbc22fb 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 @@ -68,7 +65,7 @@ bool LatestBuilds::getBuild(QString tag, Build* outBuild) { } static const std::array QML_FILE_FOR_UI_STATE = - { { "SplashScreen.qml", "qml/HFBase/CreateAccountBase.qml", "qml/HFBase/LoginBase.qml", "DisplayName.qml", + { { "qml/SplashScreen.qml", "qml/HFBase/CreateAccountBase.qml", "qml/HFBase/LoginBase.qml", "DisplayName.qml", "qml/Download.qml", "qml/DownloadFinished.qml", "qml/HFBase/Error.qml" } }; void LauncherState::ASSERT_STATE(LauncherState::ApplicationState state) { @@ -155,12 +152,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()); @@ -223,7 +233,7 @@ void LauncherState::receivedBuildsReply() { } if (shouldDownloadLauncher()) { - downloadLauncher(); + //downloadLauncher(); } getCurrentClientVersion(); } diff --git a/launchers/qt/src/LauncherState.h b/launchers/qt/src/LauncherState.h index 16137e7b87..eb87d15343 100644 --- a/launchers/qt/src/LauncherState.h +++ b/launchers/qt/src/LauncherState.h @@ -29,9 +29,9 @@ struct LatestBuilds { 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) Q_PROPERTY(SignupRequest::Error lastSignupError MEMBER _lastSignupError NOTIFY lastSignupErrorChanged); public: @@ -118,6 +118,8 @@ public: // Request Settings void requestSettings(); + Q_INVOKABLE void restart(); + // Launcher void downloadLauncher(); void installLauncher(); @@ -136,7 +138,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/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/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/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 528e984306..ee7bd85511 100644 --- a/launchers/qt/src/main.cpp +++ b/launchers/qt/src/main.cpp @@ -4,6 +4,7 @@ #include "LauncherWindow.h" #include "Launcher.h" +#include "CommandlineOptions.h" #include #include #include "Helper.h" @@ -29,46 +30,36 @@ 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; + 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")) { - 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")) { - LauncherInstaller launcherInstaller(argv[0]); +#endif + CommandlineOptions* options = CommandlineOptions::getInstance(); + options->parse(argc, argv); +#ifdef Q_OS_WIN + 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" }; QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QCoreApplication::setOrganizationName(name); - -#ifdef Q_OS_WIN - //QSharedMemory sharedMemory{ applicationName }; - //instanceMightBeRunning = !sharedMemory.create(1, QSharedMemory::ReadOnly); -#endif - Launcher launcher(argc, argv); return launcher.exec();