diff --git a/cmake/NSIS.template.in b/cmake/NSIS.template.in index 7b52b7bcc..5e7b7542a 100644 --- a/cmake/NSIS.template.in +++ b/cmake/NSIS.template.in @@ -89,19 +89,7 @@ ${IfNot} ${Errors} Quit ${EndIf} -ClearErrors -${GetOptions} $9 "/PORTABLE" $8 -${IfNot} ${Errors} - StrCpy $PortableMode 1 - StrCpy $0 $PortableDestDir -${Else} - StrCpy $PortableMode 0 - StrCpy $0 $NormalDestDir - ${If} ${Silent} - Call RequireAdmin - ${EndIf} -${EndIf} - +; Detect reinstall mode first ClearErrors ${GetOptions} $9 "/R" $8 ${IfNot} ${Errors} @@ -112,14 +100,31 @@ ${Else} StrCpy $ReinstallMode 0 ${EndIf} -${If} $InstDir == "" - ; User did not use /D to specify a directory, - ; we need to set a default based on the install mode - StrCpy $InstDir $0 +; Only parse /PORTABLE for fresh installs +${If} $ReinstallMode = 0 + ClearErrors + ${GetOptions} $9 "/PORTABLE" $8 + ${IfNot} ${Errors} + StrCpy $PortableMode 1 + StrCpy $0 $PortableDestDir + ${Else} + StrCpy $PortableMode 0 + StrCpy $0 $NormalDestDir + ${If} ${Silent} + Call RequireAdmin + ${EndIf} + ${EndIf} ${EndIf} -Call SetModeDestinationFromInstdir -; --- Detect portable install when using /R --- +${If} $InstDir == "" + ${If} $ReinstallMode = 1 + StrCpy $InstDir $NormalDestDir + ${Else} + StrCpy $InstDir $0 + ${EndIf} +${EndIf} + +; Detect portable installs during update from portable.dat ${If} $ReinstallMode = 1 IfFileExists "$InstDir\portable.dat" 0 not_portable StrCpy $PortableMode 1 @@ -131,7 +136,11 @@ ${If} $ReinstallMode = 1 portable_done: ${EndIf} +Call SetModeDestinationFromInstdir + +; Only uninstall registered installs ${If} $ReinstallMode = 1 +${AndIf} $PortableMode = 0 Call AutoUninstallIfNeeded ${EndIf} @@ -157,10 +166,10 @@ FunctionEnd Function SetModeDestinationFromInstdir -${If} $PortableMode = 0 - StrCpy $NormalDestDir $InstDir -${Else} +${If} $PortableMode = 1 StrCpy $PortableDestDir $InstDir +${Else} + StrCpy $NormalDestDir $InstDir ${EndIf} FunctionEnd diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_update.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_update.cpp index f12550fa8..b0723f6d5 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_update.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_update.cpp @@ -13,6 +13,9 @@ #include #include #include +#if defined(Q_OS_WIN) +#include +#endif DlgUpdate::DlgUpdate(QWidget *parent) : QDialog(parent) { @@ -219,9 +222,34 @@ void DlgUpdate::downloadError(const QString &errorString) void DlgUpdate::downloadSuccessful(const QUrl &filepath) { setLabel(tr("Installing...")); - // Try to open the installer. If it opens, quit Cockatrice - if (QProcess::startDetached( - QString("\"%1\" /R /D=\"%2\"").arg(filepath.toLocalFile(), QCoreApplication::applicationDirPath()))) { + + const QString installer = filepath.toLocalFile(); + const QString installDir = QDir::toNativeSeparators(QCoreApplication::applicationDirPath()); + const QString args = QString("/R /D=\"%1\"").arg(installDir); + + bool launched = false; + + qInfo() << installer; + qInfo() << installDir; + qInfo() << args; + +#if defined(Q_OS_WIN) + SHELLEXECUTEINFOW sei = {}; + sei.cbSize = sizeof(sei); + sei.fMask = SEE_MASK_NOCLOSEPROCESS; + sei.lpVerb = L"runas"; + sei.lpFile = reinterpret_cast(installer.utf16()); + sei.lpParameters = reinterpret_cast(args.utf16()); + sei.nShow = SW_SHOWNORMAL; + launched = ShellExecuteExW(&sei); + if (launched && sei.hProcess) { + CloseHandle(sei.hProcess); + } +#else + launched = QProcess::startDetached(installer, {"/R", QString("/D=%1").arg(installDir)}); +#endif + + if (launched) { QMetaObject::invokeMethod(static_cast(parent()), "close", Qt::QueuedConnection); qCInfo(DlgUpdateLog) << "Opened downloaded update file successfully - closing Cockatrice"; close();