mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 10:46:33 +02:00
Do not run elevated by default (#884)
Make the runner not run as elevated by default. Add a setting for "run PowerToys as elevated" and buttons to restart the process with the different elevation levels.
This commit is contained in:
committed by
GitHub
parent
fd8fc679be
commit
619ed234a9
@@ -6,6 +6,7 @@
|
||||
#include <common/windows_colors.h>
|
||||
|
||||
static std::wstring settings_theme = L"system";
|
||||
static bool run_as_elevated = false;
|
||||
|
||||
json::JsonObject load_general_settings() {
|
||||
auto loaded = PTSettingsHelper::load_general_settings();
|
||||
@@ -13,6 +14,7 @@ json::JsonObject load_general_settings() {
|
||||
if (settings_theme != L"dark" && settings_theme != L"light") {
|
||||
settings_theme = L"system";
|
||||
}
|
||||
run_as_elevated = loaded.GetNamedBoolean(L"run_elevated", false);
|
||||
return loaded;
|
||||
}
|
||||
|
||||
@@ -27,6 +29,9 @@ json::JsonObject get_general_settings() {
|
||||
}
|
||||
result.SetNamedValue(L"enabled", std::move(enabled));
|
||||
|
||||
bool is_elevated = is_process_elevated();
|
||||
result.SetNamedValue(L"is_elevated", json::value(is_elevated));
|
||||
result.SetNamedValue(L"run_elevated", json::value(run_as_elevated));
|
||||
result.SetNamedValue(L"theme", json::value(settings_theme));
|
||||
result.SetNamedValue(L"system_theme", json::value(WindowsColors::is_dark_mode() ? L"dark" : L"light"));
|
||||
result.SetNamedValue(L"powertoys_version", json::value(get_product_version()));
|
||||
@@ -68,6 +73,7 @@ void apply_general_settings(const json::JsonObject& general_configs) {
|
||||
}
|
||||
}
|
||||
}
|
||||
run_as_elevated = general_configs.GetNamedBoolean(L"run_elevated", false);
|
||||
if (json::has(general_configs, L"theme", json::JsonValueType::String)) {
|
||||
settings_theme = general_configs.GetNamedString(L"theme");
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <common/json.h>
|
||||
|
||||
json::JsonObject load_general_settings();
|
||||
json::JsonObject get_general_settings();
|
||||
void apply_general_settings(const json::JsonObject & general_configs);
|
||||
void start_initial_powertoys();
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include "lowlevel_keyboard_event.h"
|
||||
#include "trace.h"
|
||||
#include "general_settings.h"
|
||||
#include "restart_elevated.h"
|
||||
#include "resource.h"
|
||||
|
||||
#include <common/dpi_aware.h>
|
||||
|
||||
@@ -14,6 +16,9 @@
|
||||
#include "unhandled_exception_handler.h"
|
||||
#endif
|
||||
|
||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||
|
||||
|
||||
void chdir_current_executable() {
|
||||
// Change current directory to the path of the executable.
|
||||
WCHAR executable_path[MAX_PATH];
|
||||
@@ -24,16 +29,7 @@ void chdir_current_executable() {
|
||||
}
|
||||
}
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
|
||||
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) {
|
||||
// The app is already running
|
||||
return 0;
|
||||
}
|
||||
|
||||
int runner() {
|
||||
DPIAware::EnableDPIAwarenessForThisProcess();
|
||||
|
||||
#if _DEBUG && _WIN64
|
||||
@@ -46,12 +42,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
start_tray_icon();
|
||||
int result;
|
||||
try {
|
||||
|
||||
// Singletons initialization order needs to be preserved, first events and
|
||||
// then modules to guarantee the reverse destruction order.
|
||||
powertoys_events();
|
||||
modules();
|
||||
|
||||
chdir_current_executable();
|
||||
// Load Powertyos DLLS
|
||||
// For now only load known DLLs
|
||||
@@ -76,11 +66,59 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
Trace::EventLaunch(get_product_version());
|
||||
|
||||
result = run_message_loop();
|
||||
} catch (std::runtime_error& err) {
|
||||
} 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(NULL, std::wstring(err_what.begin(), err_what.end()).c_str(), L"Error", MB_OK | MB_ICONERROR);
|
||||
result = -1;
|
||||
}
|
||||
Trace::UnregisterProvider();
|
||||
return result;
|
||||
}
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
|
||||
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) {
|
||||
// The app is already running
|
||||
return 0;
|
||||
}
|
||||
int result = 0;
|
||||
try {
|
||||
// Singletons initialization order needs to be preserved, first events and
|
||||
// then modules to guarantee the reverse destruction order.
|
||||
SystemMenuHelperInstace();
|
||||
powertoys_events();
|
||||
modules();
|
||||
|
||||
auto general_settings = load_general_settings();
|
||||
int rvalue = 0;
|
||||
if (is_process_elevated() ||
|
||||
general_settings.GetNamedBoolean(L"run_elevated", false) == false ||
|
||||
strcmp(lpCmdLine, "--dont-elevate") == 0) {
|
||||
result = runner();
|
||||
}
|
||||
else {
|
||||
schedule_restart_as_elevated();
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
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);
|
||||
result = -1;
|
||||
}
|
||||
ReleaseMutex(runner_mutex);
|
||||
CloseHandle(runner_mutex);
|
||||
if (is_restart_scheduled()) {
|
||||
if (restart_if_scheduled() == false) {
|
||||
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);
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
stop_tray_icon();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#define APPICON 101
|
||||
#define ID_TRAY_MENU 102
|
||||
#define IDS_COULDNOT_RESTART_NONELEVATED 103
|
||||
#define IDS_COULDNOT_RESTART_ELEVATED 104
|
||||
#define IDS_ERROR 105
|
||||
#define ID_EXIT_MENU_COMMAND 40001
|
||||
#define ID_SETTINGS_MENU_COMMAND 40002
|
||||
#define ID_ABOUT_MENU_COMMAND 40003
|
||||
|
||||
37
src/runner/restart_elevated.cpp
Normal file
37
src/runner/restart_elevated.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "pch.h"
|
||||
#include "restart_elevated.h"
|
||||
#include "common/common.h"
|
||||
|
||||
enum State {
|
||||
None,
|
||||
RestartAsElevated,
|
||||
RestartAsNonElevated
|
||||
};
|
||||
static State state = None;
|
||||
|
||||
void schedule_restart_as_elevated() {
|
||||
state = RestartAsElevated;
|
||||
}
|
||||
|
||||
void schedule_restart_as_non_elevated() {
|
||||
state = RestartAsNonElevated;
|
||||
}
|
||||
|
||||
bool is_restart_scheduled() {
|
||||
return state != None;
|
||||
}
|
||||
|
||||
bool restart_if_scheduled() {
|
||||
// Make sure we have enough room, even for the long (\\?\) paths
|
||||
constexpr DWORD exe_path_size = 0xFFFF;
|
||||
auto exe_path = std::make_unique<wchar_t[]>(exe_path_size);
|
||||
GetModuleFileNameW(nullptr, exe_path.get(), exe_path_size);
|
||||
switch (state) {
|
||||
case RestartAsElevated:
|
||||
return run_elevated(exe_path.get(), {});
|
||||
case RestartAsNonElevated:
|
||||
return run_non_elevated(exe_path.get(), L"--dont-elevate");
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
5
src/runner/restart_elevated.h
Normal file
5
src/runner/restart_elevated.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
void schedule_restart_as_elevated();
|
||||
void schedule_restart_as_non_elevated();
|
||||
bool is_restart_scheduled();
|
||||
bool restart_if_scheduled();
|
||||
Binary file not shown.
@@ -63,7 +63,7 @@
|
||||
<PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<UACExecutionLevel>HighestAvailable</UACExecutionLevel>
|
||||
<UACExecutionLevel>AsInvoker</UACExecutionLevel>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Link>
|
||||
<Manifest>
|
||||
@@ -88,7 +88,7 @@
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<UACExecutionLevel>HighestAvailable</UACExecutionLevel>
|
||||
<UACExecutionLevel>AsInvoker</UACExecutionLevel>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Link>
|
||||
<Manifest>
|
||||
@@ -106,6 +106,7 @@
|
||||
<ClCompile Include="powertoys_events.cpp" />
|
||||
<ClCompile Include="powertoy_module.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="restart_elevated.cpp" />
|
||||
<ClCompile Include="settings_window.cpp" />
|
||||
<ClCompile Include="system_menu_helper.cpp" />
|
||||
<ClCompile Include="trace.cpp" />
|
||||
@@ -121,6 +122,7 @@
|
||||
<ClInclude Include="powertoys_events.h" />
|
||||
<ClInclude Include="powertoy_module.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="restart_elevated.h" />
|
||||
<ClInclude Include="settings_window.h" />
|
||||
<ClInclude Include="system_menu_helper.h" />
|
||||
<ClInclude Include="trace.h" />
|
||||
|
||||
@@ -36,6 +36,9 @@
|
||||
<ClCompile Include="system_menu_helper.cpp">
|
||||
<Filter>Utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="restart_elevated.cpp">
|
||||
<Filter>Utils</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="pch.h" />
|
||||
@@ -73,6 +76,9 @@
|
||||
<ClInclude Include="system_menu_helper.h">
|
||||
<Filter>Utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="restart_elevated.h">
|
||||
<Filter>Utils</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Utils">
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include "tray_icon.h"
|
||||
#include "general_settings.h"
|
||||
#include "common/windows_colors.h"
|
||||
#include "common/common.h"
|
||||
#include "restart_elevated.h"
|
||||
|
||||
#include <common/json.h>
|
||||
|
||||
@@ -48,10 +50,25 @@ void dispatch_json_action_to_module(const json::JsonObject& powertoys_configs)
|
||||
for (const auto& powertoy_element : powertoys_configs)
|
||||
{
|
||||
const std::wstring name{ powertoy_element.Key().c_str() };
|
||||
if (modules().find(name) != modules().end())
|
||||
// Currently, there is only one custom action in the general settings screen,
|
||||
// so it has to be the "restart as (non-)elevated" button.
|
||||
if (name == L"general")
|
||||
{
|
||||
if (is_process_elevated())
|
||||
{
|
||||
schedule_restart_as_non_elevated();
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
schedule_restart_as_elevated();
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
}
|
||||
else if (modules().find(name) != modules().end())
|
||||
{
|
||||
const auto element = powertoy_element.Value().Stringify();
|
||||
modules().at(name).call_custom_action(element.c_str());
|
||||
modules().at(name).call_custom_action(element.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,10 @@ LRESULT __stdcall tray_icon_window_proc(HWND window, UINT message, WPARAM wparam
|
||||
}
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
Shell_NotifyIcon(NIM_DELETE, &tray_icon_data);
|
||||
if (tray_icon_created) {
|
||||
Shell_NotifyIcon(NIM_DELETE, &tray_icon_data);
|
||||
tray_icon_created = false;
|
||||
}
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
case WM_CLOSE:
|
||||
@@ -171,3 +174,9 @@ void start_tray_icon() {
|
||||
tray_icon_created = Shell_NotifyIcon(NIM_ADD, &tray_icon_data) == TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void stop_tray_icon() {
|
||||
if (tray_icon_created) {
|
||||
SendMessage(tray_icon_hwnd, WM_CLOSE, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
// Start the Tray Icon
|
||||
void start_tray_icon();
|
||||
// Stop the Tray Icon
|
||||
void stop_tray_icon();
|
||||
// Open the Settings Window
|
||||
void open_settings_window();
|
||||
// Callback type to be called by the tray icon loop
|
||||
|
||||
Reference in New Issue
Block a user