mirror of
https://github.com/microsoft/PowerToys.git
synced 2024-12-01 01:49:06 +08:00
[Peek]Create Setting to run not elevated (#26308)
* [Peek]Create Setting to run not elevated * Optionally add access permissions to the handles
This commit is contained in:
parent
4560abe557
commit
42e707966d
@ -353,7 +353,7 @@ struct ProcessInfo
|
|||||||
DWORD processID = {};
|
DWORD processID = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::optional<ProcessInfo> RunNonElevatedFailsafe(const std::wstring& file, const std::wstring& params, const std::wstring& working_dir)
|
inline std::optional<ProcessInfo> RunNonElevatedFailsafe(const std::wstring& file, const std::wstring& params, const std::wstring& working_dir, DWORD handleAccess = 0)
|
||||||
{
|
{
|
||||||
bool launched = RunNonElevatedEx(file, params, working_dir);
|
bool launched = RunNonElevatedEx(file, params, working_dir);
|
||||||
if (!launched)
|
if (!launched)
|
||||||
@ -373,7 +373,7 @@ inline std::optional<ProcessInfo> RunNonElevatedFailsafe(const std::wstring& fil
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto handles = getProcessHandlesByName(std::filesystem::path{ file }.filename().wstring(), PROCESS_QUERY_INFORMATION | SYNCHRONIZE);
|
auto handles = getProcessHandlesByName(std::filesystem::path{ file }.filename().wstring(), PROCESS_QUERY_INFORMATION | SYNCHRONIZE | handleAccess );
|
||||||
|
|
||||||
if (handles.empty())
|
if (handles.empty())
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <atlbase.h>
|
#include <atlbase.h>
|
||||||
#include <exdisp.h>
|
#include <exdisp.h>
|
||||||
#include <comdef.h>
|
#include <comdef.h>
|
||||||
|
#include <common/utils/elevation.h>
|
||||||
|
|
||||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
||||||
|
|
||||||
@ -40,6 +41,7 @@ namespace
|
|||||||
const wchar_t JSON_KEY_SHIFT[] = L"shift";
|
const wchar_t JSON_KEY_SHIFT[] = L"shift";
|
||||||
const wchar_t JSON_KEY_CODE[] = L"code";
|
const wchar_t JSON_KEY_CODE[] = L"code";
|
||||||
const wchar_t JSON_KEY_ACTIVATION_SHORTCUT[] = L"ActivationShortcut";
|
const wchar_t JSON_KEY_ACTIVATION_SHORTCUT[] = L"ActivationShortcut";
|
||||||
|
const wchar_t JSON_KEY_ALWAYS_RUN_NOT_ELEVATED[] = L"AlwaysRunNotElevated";
|
||||||
}
|
}
|
||||||
|
|
||||||
// The PowerToy name that will be shown in the settings.
|
// The PowerToy name that will be shown in the settings.
|
||||||
@ -56,7 +58,10 @@ private:
|
|||||||
|
|
||||||
Hotkey m_hotkey;
|
Hotkey m_hotkey;
|
||||||
|
|
||||||
HANDLE m_hProcess;
|
// If we should always try to run Peek non-elevated.
|
||||||
|
bool m_alwaysRunNotElevated = true;
|
||||||
|
|
||||||
|
HANDLE m_hProcess = 0;
|
||||||
|
|
||||||
HANDLE m_hInvokeEvent;
|
HANDLE m_hInvokeEvent;
|
||||||
|
|
||||||
@ -89,22 +94,32 @@ private:
|
|||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
Logger::error("Failed to initialize Peek start settings");
|
Logger::error("Failed to initialize Peek hotkey settings");
|
||||||
|
|
||||||
set_default_settings();
|
set_default_key_settings();
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto jsonAlwaysRunNotElevatedObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_ALWAYS_RUN_NOT_ELEVATED);
|
||||||
|
m_alwaysRunNotElevated = jsonAlwaysRunNotElevatedObject.GetNamedBoolean(L"value");
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
Logger::error("Failed to initialize Always Run Not Elevated option. Setting to default.");
|
||||||
|
|
||||||
|
m_alwaysRunNotElevated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger::info("Peek settings are empty");
|
Logger::info("Peek settings are empty");
|
||||||
|
set_default_key_settings();
|
||||||
set_default_settings();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_default_settings()
|
void set_default_key_settings()
|
||||||
{
|
{
|
||||||
Logger::info("Peek is going to use default settings");
|
Logger::info("Peek is going to use default key settings");
|
||||||
m_hotkey.win = false;
|
m_hotkey.win = false;
|
||||||
m_hotkey.alt = false;
|
m_hotkey.alt = false;
|
||||||
m_hotkey.shift = false;
|
m_hotkey.shift = false;
|
||||||
@ -236,6 +251,10 @@ private:
|
|||||||
|
|
||||||
bool is_viewer_running()
|
bool is_viewer_running()
|
||||||
{
|
{
|
||||||
|
if (m_hProcess == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return WaitForSingleObject(m_hProcess, 0) == WAIT_TIMEOUT;
|
return WaitForSingleObject(m_hProcess, 0) == WAIT_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,24 +267,43 @@ private:
|
|||||||
std::wstring executable_args = L"";
|
std::wstring executable_args = L"";
|
||||||
executable_args.append(std::to_wstring(powertoys_pid));
|
executable_args.append(std::to_wstring(powertoys_pid));
|
||||||
|
|
||||||
SHELLEXECUTEINFOW sei{ sizeof(sei) };
|
if (m_alwaysRunNotElevated && is_process_elevated(false))
|
||||||
|
|
||||||
sei.fMask = { SEE_MASK_NOCLOSEPROCESS };
|
|
||||||
sei.lpVerb = L"open";
|
|
||||||
sei.lpFile = L"modules\\Peek\\Powertoys.Peek.UI.exe";
|
|
||||||
sei.nShow = SW_SHOWNORMAL;
|
|
||||||
sei.lpParameters = executable_args.data();
|
|
||||||
|
|
||||||
if (ShellExecuteExW(&sei))
|
|
||||||
{
|
{
|
||||||
Logger::trace("Successfully started the PeekViewer process");
|
Logger::trace("Starting Peek non elevated from elevated process");
|
||||||
|
const auto modulePath = get_module_folderpath();
|
||||||
|
std::wstring runExecutablePath = modulePath;
|
||||||
|
runExecutablePath += L"\\modules\\Peek\\PowerToys.Peek.UI.exe";
|
||||||
|
std::optional<ProcessInfo> processStartedInfo = RunNonElevatedFailsafe(runExecutablePath, executable_args, modulePath, PROCESS_QUERY_INFORMATION | SYNCHRONIZE | PROCESS_TERMINATE);
|
||||||
|
if (processStartedInfo.has_value())
|
||||||
|
{
|
||||||
|
m_hProcess = processStartedInfo.value().processHandle.release();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger::error(L"PeekViewer failed to start not elevated.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger::error(L"PeekViewer failed to start. {}", get_last_error_or_default(GetLastError()));
|
SHELLEXECUTEINFOW sei{ sizeof(sei) };
|
||||||
}
|
|
||||||
|
|
||||||
m_hProcess = sei.hProcess;
|
sei.fMask = { SEE_MASK_NOCLOSEPROCESS };
|
||||||
|
sei.lpVerb = L"open";
|
||||||
|
sei.lpFile = L"modules\\Peek\\PowerToys.Peek.UI.exe";
|
||||||
|
sei.nShow = SW_SHOWNORMAL;
|
||||||
|
sei.lpParameters = executable_args.data();
|
||||||
|
|
||||||
|
if (ShellExecuteExW(&sei))
|
||||||
|
{
|
||||||
|
Logger::trace("Successfully started the PeekViewer process");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger::error(L"PeekViewer failed to start. {}", get_last_error_or_default(GetLastError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_hProcess = sei.hProcess;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -355,7 +393,14 @@ public:
|
|||||||
if (m_enabled)
|
if (m_enabled)
|
||||||
{
|
{
|
||||||
ResetEvent(m_hInvokeEvent);
|
ResetEvent(m_hInvokeEvent);
|
||||||
TerminateProcess(m_hProcess, 1);
|
auto result = TerminateProcess(m_hProcess, 1);
|
||||||
|
if (result == 0)
|
||||||
|
{
|
||||||
|
int error = GetLastError();
|
||||||
|
Logger::trace("Couldn't terminate the process. Last error: {}", error);
|
||||||
|
}
|
||||||
|
CloseHandle(m_hProcess);
|
||||||
|
m_hProcess = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_enabled = false;
|
m_enabled = false;
|
||||||
|
@ -62,6 +62,7 @@
|
|||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||||
|
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220914.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220914.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<Import Project="..\..\..\..\deps\spdlog.props" />
|
<Import Project="..\..\..\..\deps\spdlog.props" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
@ -72,5 +73,6 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||||
|
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220914.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220914.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||||
</Target>
|
</Target>
|
||||||
</Project>
|
</Project>
|
@ -11,10 +11,13 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||||||
public PeekProperties()
|
public PeekProperties()
|
||||||
{
|
{
|
||||||
ActivationShortcut = new HotkeySettings(false, true, false, false, 0x20);
|
ActivationShortcut = new HotkeySettings(false, true, false, false, 0x20);
|
||||||
|
AlwaysRunNotElevated = new BoolProperty(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HotkeySettings ActivationShortcut { get; set; }
|
public HotkeySettings ActivationShortcut { get; set; }
|
||||||
|
|
||||||
|
public BoolProperty AlwaysRunNotElevated { get; set; }
|
||||||
|
|
||||||
public override string ToString() => JsonSerializer.Serialize(this);
|
public override string ToString() => JsonSerializer.Serialize(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2833,6 +2833,16 @@ From there, simply click on one of the supported files in the File Explorer and
|
|||||||
<value>Enable Peek</value>
|
<value>Enable Peek</value>
|
||||||
<comment>Peek is a product name, do not loc</comment>
|
<comment>Peek is a product name, do not loc</comment>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Peek_BehaviorHeader.Header" xml:space="preserve">
|
||||||
|
<value>Behavior</value>
|
||||||
|
</data>
|
||||||
|
<data name="Peek_AlwaysRunNotElevated.Header" xml:space="preserve">
|
||||||
|
<value>Always run not elevated, even when PowerToys is elevated</value>
|
||||||
|
</data>
|
||||||
|
<data name="Peek_AlwaysRunNotElevated.Description" xml:space="preserve">
|
||||||
|
<value>Tries to run Peek without elevated permissions, to fix access to network shares. You need to disable and re-enable Peek for changes to this value to take effect.</value>
|
||||||
|
<comment>Peek is a product name, do not loc</comment>
|
||||||
|
</data>
|
||||||
<data name="FancyZones_DisableRoundCornersOnWindowSnap.Content" xml:space="preserve">
|
<data name="FancyZones_DisableRoundCornersOnWindowSnap.Content" xml:space="preserve">
|
||||||
<value>Disable round corners when window is snapped</value>
|
<value>Disable round corners when window is snapped</value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -109,6 +109,20 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool AlwaysRunNotElevated
|
||||||
|
{
|
||||||
|
get => _peekSettings.Properties.AlwaysRunNotElevated.Value;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_peekSettings.Properties.AlwaysRunNotElevated.Value != value)
|
||||||
|
{
|
||||||
|
_peekSettings.Properties.AlwaysRunNotElevated.Value = value;
|
||||||
|
OnPropertyChanged(nameof(AlwaysRunNotElevated));
|
||||||
|
NotifySettingsChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void NotifySettingsChanged()
|
private void NotifySettingsChanged()
|
||||||
{
|
{
|
||||||
// Using InvariantCulture as this is an IPC message
|
// Using InvariantCulture as this is an IPC message
|
||||||
|
@ -31,6 +31,14 @@
|
|||||||
<controls:ShortcutControl MinWidth="{StaticResource SettingActionControlMinWidth}" HotkeySettings="{x:Bind Path=ViewModel.ActivationShortcut, Mode=TwoWay}" />
|
<controls:ShortcutControl MinWidth="{StaticResource SettingActionControlMinWidth}" HotkeySettings="{x:Bind Path=ViewModel.ActivationShortcut, Mode=TwoWay}" />
|
||||||
</labs:SettingsCard>
|
</labs:SettingsCard>
|
||||||
</controls:SettingsGroup>
|
</controls:SettingsGroup>
|
||||||
|
<controls:SettingsGroup x:Uid="Peek_BehaviorHeader" IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsEnabled}">
|
||||||
|
<labs:SettingsCard x:Uid="Peek_AlwaysRunNotElevated" HeaderIcon="{ui:FontIcon FontFamily={StaticResource SymbolThemeFontFamily}, Glyph=}">
|
||||||
|
<ToggleSwitch
|
||||||
|
x:Uid="ToggleSwitch"
|
||||||
|
IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.AlwaysRunNotElevated}" />
|
||||||
|
</labs:SettingsCard>
|
||||||
|
</controls:SettingsGroup>
|
||||||
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</controls:SettingsPageControl.ModuleContent>
|
</controls:SettingsPageControl.ModuleContent>
|
||||||
<controls:SettingsPageControl.PrimaryLinks>
|
<controls:SettingsPageControl.PrimaryLinks>
|
||||||
|
Loading…
Reference in New Issue
Block a user