diff --git a/Source/Core/Common/FileUtil.cpp b/Source/Core/Common/FileUtil.cpp index b86b9f9dd4..74d2855659 100644 --- a/Source/Core/Common/FileUtil.cpp +++ b/Source/Core/Common/FileUtil.cpp @@ -664,33 +664,42 @@ std::string GetBundleDirectory() } #endif -std::string& GetExeDirectory() +std::string GetExePath() { - static std::string DolphinPath; - if (DolphinPath.empty()) + static std::string dolphin_path; + if (dolphin_path.empty()) { #ifdef _WIN32 - TCHAR Dolphin_exe_Path[2048]; - TCHAR Dolphin_exe_Clean_Path[MAX_PATH]; - GetModuleFileName(nullptr, Dolphin_exe_Path, 2048); - if (_tfullpath(Dolphin_exe_Clean_Path, Dolphin_exe_Path, MAX_PATH) != nullptr) - DolphinPath = TStrToUTF8(Dolphin_exe_Clean_Path); + TCHAR dolphin_exe_path[2048]; + TCHAR dolphin_exe_expanded_path[MAX_PATH]; + GetModuleFileName(nullptr, dolphin_exe_path, ARRAYSIZE(dolphin_exe_path)); + if (_tfullpath(dolphin_exe_expanded_path, dolphin_exe_path, + ARRAYSIZE(dolphin_exe_expanded_path)) != nullptr) + dolphin_path = TStrToUTF8(dolphin_exe_expanded_path); else - DolphinPath = TStrToUTF8(Dolphin_exe_Path); - DolphinPath = DolphinPath.substr(0, DolphinPath.find_last_of('\\')); + dolphin_path = TStrToUTF8(dolphin_exe_path); #else - char Dolphin_exe_Path[PATH_MAX]; - ssize_t len = ::readlink("/proc/self/exe", Dolphin_exe_Path, sizeof(Dolphin_exe_Path)); - if (len == -1 || len == sizeof(Dolphin_exe_Path)) + char dolphin_exe_path[PATH_MAX]; + ssize_t len = ::readlink("/proc/self/exe", dolphin_exe_path, sizeof(dolphin_exe_path)); + if (len == -1 || len == sizeof(dolphin_exe_path)) { len = 0; } - Dolphin_exe_Path[len] = '\0'; - DolphinPath = Dolphin_exe_Path; - DolphinPath = DolphinPath.substr(0, DolphinPath.rfind('/')); + dolphin_exe_path[len] = '\0'; + dolphin_path = dolphin_exe_path; #endif } - return DolphinPath; + return dolphin_path; +} + +std::string GetExeDirectory() +{ + std::string exe_path = GetExePath(); +#ifdef _WIN32 + return exe_path.substr(0, exe_path.rfind('\\')); +#else + return exe_path.substr(0, exe_path.rfind('/')); +#endif } std::string GetSysDirectory() @@ -882,4 +891,4 @@ bool ReadFileToString(const std::string& filename, std::string& str) return retval; } -} // namespace +} // namespace File diff --git a/Source/Core/Common/FileUtil.h b/Source/Core/Common/FileUtil.h index 694ec11128..5b942d8764 100644 --- a/Source/Core/Common/FileUtil.h +++ b/Source/Core/Common/FileUtil.h @@ -191,7 +191,8 @@ void SetSysDirectory(const std::string& path); std::string GetBundleDirectory(); #endif -std::string& GetExeDirectory(); +std::string GetExePath(); +std::string GetExeDirectory(); bool WriteStringToFile(const std::string& str, const std::string& filename); bool ReadFileToString(const std::string& filename, std::string& str); diff --git a/Source/Core/DolphinQt2/Updater.cpp b/Source/Core/DolphinQt2/Updater.cpp index 7a6352d19b..cee7bc494e 100644 --- a/Source/Core/DolphinQt2/Updater.cpp +++ b/Source/Core/DolphinQt2/Updater.cpp @@ -80,7 +80,8 @@ void Updater::OnUpdateAvailable(const NewVersionInformation& info) if (choice == QDialog::Accepted) { - TriggerUpdate(info); + TriggerUpdate(info, later ? AutoUpdateChecker::RestartMode::NO_RESTART_AFTER_UPDATE : + AutoUpdateChecker::RestartMode::RESTART_AFTER_UPDATE); if (!later) m_parent->close(); diff --git a/Source/Core/UICommon/AutoUpdate.cpp b/Source/Core/UICommon/AutoUpdate.cpp index dc094f29ac..916176faaf 100644 --- a/Source/Core/UICommon/AutoUpdate.cpp +++ b/Source/Core/UICommon/AutoUpdate.cpp @@ -111,7 +111,8 @@ void AutoUpdateChecker::CheckForUpdate() OnUpdateAvailable(nvi); } -void AutoUpdateChecker::TriggerUpdate(const AutoUpdateChecker::NewVersionInformation& info) +void AutoUpdateChecker::TriggerUpdate(const AutoUpdateChecker::NewVersionInformation& info, + AutoUpdateChecker::RestartMode restart_mode) { #ifdef _WIN32 std::map updater_flags; @@ -122,6 +123,9 @@ void AutoUpdateChecker::TriggerUpdate(const AutoUpdateChecker::NewVersionInforma updater_flags["install-base-path"] = File::GetExeDirectory(); updater_flags["log-file"] = File::GetExeDirectory() + DIR_SEP + UPDATER_LOG_FILE; + if (restart_mode == RestartMode::RESTART_AFTER_UPDATE) + updater_flags["binary-to-restart"] = File::GetExePath(); + // Copy the updater so it can update itself if needed. std::string updater_path = File::GetExeDirectory() + DIR_SEP + UPDATER_FILENAME; std::string reloc_updater_path = File::GetExeDirectory() + DIR_SEP + UPDATER_RELOC_FILENAME; diff --git a/Source/Core/UICommon/AutoUpdate.h b/Source/Core/UICommon/AutoUpdate.h index b0de6006de..7c75100433 100644 --- a/Source/Core/UICommon/AutoUpdate.h +++ b/Source/Core/UICommon/AutoUpdate.h @@ -33,7 +33,12 @@ public: }; // Starts the updater process, which will wait in the background until the current process exits. - void TriggerUpdate(const NewVersionInformation& info); + enum class RestartMode + { + NO_RESTART_AFTER_UPDATE = 0, + RESTART_AFTER_UPDATE, + }; + void TriggerUpdate(const NewVersionInformation& info, RestartMode restart_mode); protected: virtual void OnUpdateAvailable(const NewVersionInformation& info) = 0; diff --git a/Source/Core/Updater/Main.cpp b/Source/Core/Updater/Main.cpp index 3e647c6978..28ca2b0c7f 100644 --- a/Source/Core/Updater/Main.cpp +++ b/Source/Core/Updater/Main.cpp @@ -47,6 +47,7 @@ struct Options std::string next_manifest_url; std::string content_store_url; std::string install_base_path; + std::optional binary_to_restart; std::optional parent_pid; std::optional log_file; }; @@ -90,6 +91,10 @@ std::optional ParseCommandLine(PCWSTR command_line) .dest("install-base-path") .help("Base path of the Dolphin install to be updated.") .metavar("PATH"); + parser.add_option("--binary-to-restart") + .dest("binary-to-restart") + .help("Binary to restart after the update is over.") + .metavar("PATH"); parser.add_option("--log-file") .dest("log-file") .help("File where to log updater debug output.") @@ -123,6 +128,8 @@ std::optional ParseCommandLine(PCWSTR command_line) opts.install_base_path = options["install-base-path"]; // Optional arguments. + if (options.is_set("binary-to-restart")) + opts.binary_to_restart = options["binary-to-restart"]; if (options.is_set("parent-pid")) opts.parent_pid = (DWORD)options.get("parent-pid"); if (options.is_set("log-file")) @@ -685,5 +692,11 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine fprintf(log_fp, "Failed to apply the update.\n"); CleanUpTempDir(temp_dir, todo); + + if (opts.binary_to_restart) + { + ShellExecuteW(nullptr, L"open", UTF8ToUTF16(*opts.binary_to_restart).c_str(), L"", nullptr, + SW_SHOW); + } return !ok; }