diff options
| author | Shawn Hoffman <godisgovernment@gmail.com> | 2023-03-09 18:23:12 -0800 |
|---|---|---|
| committer | Shawn Hoffman <godisgovernment@gmail.com> | 2023-03-11 12:58:33 -0800 |
| commit | 0a8725e4a97de50b1e267a67492e0cd0c4275010 (patch) | |
| tree | 428c33e498ddbcca3ca70ac7c4b2ae02d0e72d85 /Source/Core/WinUpdater | |
| parent | de0bc06856bb4d1c36a62c84bc4f8e245138c090 (diff) | |
updater: add test for update flow
currently windows-only
Diffstat (limited to 'Source/Core/WinUpdater')
| -rw-r--r-- | Source/Core/WinUpdater/Platform.cpp | 23 | ||||
| -rw-r--r-- | Source/Core/WinUpdater/WinUI.cpp | 31 |
2 files changed, 44 insertions, 10 deletions
diff --git a/Source/Core/WinUpdater/Platform.cpp b/Source/Core/WinUpdater/Platform.cpp index 1cfa6b4327..0a2b62c5f9 100644 --- a/Source/Core/WinUpdater/Platform.cpp +++ b/Source/Core/WinUpdater/Platform.cpp @@ -194,9 +194,12 @@ static bool VCRuntimeUpdate(const BuildInfo& build_info) Common::ScopeGuard redist_deleter([&] { File::Delete(redist_path_u8); }); - // The installer also supports /passive and /quiet. We pass neither to allow the user to see and - // interact with the installer. + // The installer also supports /passive and /quiet. We normally pass neither (the + // exception being test automation) to allow the user to see and interact with the installer. std::wstring cmdline = redist_path.filename().wstring() + L" /install /norestart"; + if (UI::IsTestMode()) + cmdline += L" /passive /quiet"; + STARTUPINFOW startup_info{.cb = sizeof(startup_info)}; PROCESS_INFORMATION process_info; if (!CreateProcessW(redist_path.c_str(), cmdline.data(), nullptr, nullptr, TRUE, 0, nullptr, @@ -213,7 +216,8 @@ static bool VCRuntimeUpdate(const BuildInfo& build_info) CloseHandle(process_info.hProcess); // NOTE: Some nonzero exit codes can still be considered success (e.g. if installation was // bypassed because the same version already installed). - return has_exit_code && exit_code == EXIT_SUCCESS; + return has_exit_code && + (exit_code == ERROR_SUCCESS || exit_code == ERROR_SUCCESS_REBOOT_REQUIRED); } static BuildVersion CurrentOSVersion() @@ -287,11 +291,16 @@ bool CheckBuildInfo(const BuildInfos& build_infos) // Check if application being launched needs more recent version of VC Redist. If so, download // latest updater and execute it. auto vc_check = VCRuntimeVersionCheck(build_infos); - if (vc_check.status != VersionCheckStatus::NothingToDo) + const auto is_test_mode = UI::IsTestMode(); + if (vc_check.status != VersionCheckStatus::NothingToDo || is_test_mode) { - // Don't bother checking status of the install itself, just check if we actually see the new - // version. - VCRuntimeUpdate(build_infos.next); + auto update_ok = VCRuntimeUpdate(build_infos.next); + if (!update_ok && is_test_mode) + { + // For now, only check return value when test automation is running. + // The vc_redist exe may return other non-zero status that we don't check for, yet. + return false; + } vc_check = VCRuntimeVersionCheck(build_infos); if (vc_check.status == VersionCheckStatus::UpdateRequired) { diff --git a/Source/Core/WinUpdater/WinUI.cpp b/Source/Core/WinUpdater/WinUI.cpp index 1671f43457..8e3e7c375d 100644 --- a/Source/Core/WinUpdater/WinUI.cpp +++ b/Source/Core/WinUpdater/WinUI.cpp @@ -3,12 +3,14 @@ #include "UpdaterCommon/UI.h" +#include <cstdlib> #include <string> #include <thread> #include <Windows.h> #include <CommCtrl.h> #include <ShObjIdl.h> +#include <ShlObj.h> #include <shellapi.h> #include <wrl/client.h> @@ -251,11 +253,34 @@ void Stop() ui_thread.join(); } +bool IsTestMode() +{ + return std::getenv("DOLPHIN_UPDATE_SERVER_URL") != nullptr; +} + void LaunchApplication(std::string path) { - // Indirectly start the application via explorer. This effectively drops admin priviliges because - // explorer is running as current user. - ShellExecuteW(nullptr, nullptr, L"explorer.exe", UTF8ToWString(path).c_str(), nullptr, SW_SHOW); + const auto wpath = UTF8ToWString(path); + if (IsUserAnAdmin()) + { + // Indirectly start the application via explorer. This effectively drops admin privileges + // because explorer is running as current user. + ShellExecuteW(nullptr, nullptr, L"explorer.exe", wpath.c_str(), nullptr, SW_SHOW); + } + else + { + std::wstring cmdline = wpath; + STARTUPINFOW startup_info{.cb = sizeof(startup_info)}; + PROCESS_INFORMATION process_info; + if (IsTestMode()) + SetEnvironmentVariableA("DOLPHIN_UPDATE_TEST_DONE", "1"); + if (CreateProcessW(wpath.c_str(), cmdline.data(), nullptr, nullptr, TRUE, 0, nullptr, nullptr, + &startup_info, &process_info)) + { + CloseHandle(process_info.hThread); + CloseHandle(process_info.hProcess); + } + } } void Sleep(int sleep) |
