diff --git a/src/common/common.cpp b/src/common/common.cpp index 84ada8d1080..73b3cef1896 100644 --- a/src/common/common.cpp +++ b/src/common/common.cpp @@ -310,6 +310,33 @@ bool run_non_elevated(const std::wstring& file, const std::wstring& params) { return succedded; } +bool run_same_elevation(const std::wstring& file, const std::wstring& params) { + auto executable_args = file; + if (!params.empty()) { + executable_args += L" " + params; + } + STARTUPINFO si = { 0 }; + PROCESS_INFORMATION pi = { 0 }; + auto succedded = CreateProcessW(file.c_str(), + const_cast(executable_args.c_str()), + nullptr, + nullptr, + FALSE, + 0, + nullptr, + nullptr, + &si, + &pi); + if (pi.hProcess) { + CloseHandle(pi.hProcess); + } + if (pi.hThread) { + CloseHandle(pi.hThread); + } + return succedded; +} + + std::wstring get_process_path(HWND window) noexcept { const static std::wstring app_frame_host = L"ApplicationFrameHost.exe"; DWORD pid{}; diff --git a/src/common/common.h b/src/common/common.h index d9e1dc19764..81525f9361c 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -58,6 +58,9 @@ bool run_elevated(const std::wstring& file, const std::wstring& params); // Run command as non-elevated user, returns true if succeeded bool run_non_elevated(const std::wstring& file, const std::wstring& params); +// Run command with the same elevation, returns true if succedded +bool run_same_elevation(const std::wstring& file, const std::wstring& params); + // Get the executable path or module name for modern apps std::wstring get_process_path(DWORD pid) noexcept; // Get the executable path or module name for modern apps diff --git a/src/runner/main.cpp b/src/runner/main.cpp index 0e711094aae..b9c82cc3c4f 100644 --- a/src/runner/main.cpp +++ b/src/runner/main.cpp @@ -80,7 +80,7 @@ int runner() catch (std::runtime_error& err) { std::string err_what = err.what(); - MessageBoxW(NULL, std::wstring(err_what.begin(), err_what.end()).c_str(), L"Error", MB_OK | MB_ICONERROR); + MessageBoxW(nullptr, std::wstring(err_what.begin(), err_what.end()).c_str(), GET_RESOURCE_STRING(IDS_ERROR).c_str(), MB_OK | MB_ICONERROR | MB_SETFOREGROUND); result = -1; } Trace::UnregisterProvider(); @@ -92,8 +92,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine WCHAR username[UNLEN + 1]; DWORD username_length = UNLEN + 1; GetUserNameW(username, &username_length); - auto runner_mutex = CreateMutexW(NULL, TRUE, (std::wstring(L"Local\\PowerToyRunMutex") + username).c_str()); - if (runner_mutex == NULL || GetLastError() == ERROR_ALREADY_EXISTS) + auto runner_mutex = CreateMutexW(nullptr, TRUE, (std::wstring(L"Local\\PowerToyRunMutex") + username).c_str()); + if (runner_mutex == nullptr || GetLastError() == ERROR_ALREADY_EXISTS) { // The app is already running return 0; @@ -124,7 +124,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine catch (std::runtime_error& err) { std::string err_what = err.what(); - MessageBoxW(NULL, std::wstring(err_what.begin(), err_what.end()).c_str(), GET_RESOURCE_STRING(IDS_ERROR).c_str(), MB_OK | MB_ICONERROR); + MessageBoxW(nullptr, std::wstring(err_what.begin(), err_what.end()).c_str(), GET_RESOURCE_STRING(IDS_ERROR).c_str(), MB_OK | MB_ICONERROR); result = -1; } ReleaseMutex(runner_mutex); @@ -135,7 +135,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine { auto text = is_process_elevated() ? GET_RESOURCE_STRING(IDS_COULDNOT_RESTART_NONELEVATED) : GET_RESOURCE_STRING(IDS_COULDNOT_RESTART_ELEVATED); - MessageBoxW(NULL, text.c_str(), GET_RESOURCE_STRING(IDS_ERROR).c_str(), MB_OK | MB_ICONERROR); + MessageBoxW(nullptr, text.c_str(), GET_RESOURCE_STRING(IDS_ERROR).c_str(), MB_OK | MB_ICONERROR | MB_SETFOREGROUND); + + restart_same_elevation(); result = -1; } } diff --git a/src/runner/restart_elevated.cpp b/src/runner/restart_elevated.cpp index 0f05aa86a01..410c9884e04 100644 --- a/src/runner/restart_elevated.cpp +++ b/src/runner/restart_elevated.cpp @@ -41,3 +41,11 @@ bool restart_if_scheduled() return false; } } + +bool restart_same_elevation() +{ + constexpr DWORD exe_path_size = 0xFFFF; + auto exe_path = std::make_unique(exe_path_size); + GetModuleFileNameW(nullptr, exe_path.get(), exe_path_size); + return run_same_elevation(exe_path.get(), {}); +} diff --git a/src/runner/restart_elevated.h b/src/runner/restart_elevated.h index 8a84f7abe0b..22cc7f30613 100644 --- a/src/runner/restart_elevated.h +++ b/src/runner/restart_elevated.h @@ -3,3 +3,4 @@ void schedule_restart_as_elevated(); void schedule_restart_as_non_elevated(); bool is_restart_scheduled(); bool restart_if_scheduled(); +bool restart_same_elevation(); diff --git a/src/runner/runner.rc b/src/runner/runner.rc index 239c9f72c6a..c8b2ba4b828 100644 Binary files a/src/runner/runner.rc and b/src/runner/runner.rc differ