diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt
index f5877b1a4d..200b0b0272 100644
--- a/.github/actions/spell-check/expect.txt
+++ b/.github/actions/spell-check/expect.txt
@@ -388,6 +388,7 @@ DCOM
dcomp
DComposition
ddf
+DDLM
Deact
debian
debugbreak
@@ -1295,6 +1296,7 @@ MYTZ
NAMECHANGE
nameof
namespace
+namespaceanddescendants
Navassa
NCACTIVATE
ncc
diff --git a/installer/PowerToysSetup/PowerToys.wxs b/installer/PowerToysSetup/PowerToys.wxs
index 7137f5dd53..0182c26c15 100644
--- a/installer/PowerToysSetup/PowerToys.wxs
+++ b/installer/PowerToysSetup/PowerToys.wxs
@@ -10,8 +10,8 @@
-
-
+
+
@@ -27,8 +27,8 @@
-
-
+
+
@@ -110,18 +110,19 @@
UninstallCommand="/silent /uninstall">
spsv;
-
+
// Desktop may not be available on startup
auto attempts = 5;
for (auto i = 1; i <= attempts; i++)
@@ -492,31 +492,4 @@ inline bool check_user_is_admin()
freeMemory(pSID, pGroupInfo);
return false;
-}
-
-inline bool is_process_of_window_elevated(HWND window)
-{
- DWORD pid = 0;
- GetWindowThreadProcessId(window, &pid);
- if (!pid)
- {
- return false;
- }
-
- wil::unique_handle hProcess{ OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION,
- FALSE,
- pid) };
-
- wil::unique_handle token;
-
- if (OpenProcessToken(hProcess.get(), TOKEN_QUERY, &token))
- {
- TOKEN_ELEVATION elevation;
- DWORD size;
- if (GetTokenInformation(token.get(), TokenElevation, &elevation, sizeof(elevation), &size))
- {
- return elevation.TokenIsElevated != 0;
- }
- }
- return false;
-}
+}
\ No newline at end of file
diff --git a/src/modules/fancyzones/FancyZonesLib/WindowUtils.cpp b/src/modules/fancyzones/FancyZonesLib/WindowUtils.cpp
index 5033d861e7..9b5cc732d8 100644
--- a/src/modules/fancyzones/FancyZonesLib/WindowUtils.cpp
+++ b/src/modules/fancyzones/FancyZonesLib/WindowUtils.cpp
@@ -3,11 +3,10 @@
#include
#include
-#include
-#include
#include
#include
#include
+#include
#include
#include
@@ -246,7 +245,30 @@ bool FancyZonesWindowUtils::IsCandidateForZoning(HWND window)
bool FancyZonesWindowUtils::IsProcessOfWindowElevated(HWND window)
{
- return is_process_of_window_elevated(window);
+ DWORD pid = 0;
+ GetWindowThreadProcessId(window, &pid);
+ if (!pid)
+ {
+ return false;
+ }
+
+ wil::unique_handle hProcess{ OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION,
+ FALSE,
+ pid) };
+
+ wil::unique_handle token;
+ bool elevated = false;
+
+ if (OpenProcessToken(hProcess.get(), TOKEN_QUERY, &token))
+ {
+ TOKEN_ELEVATION elevation;
+ DWORD size;
+ if (GetTokenInformation(token.get(), TokenElevation, &elevation, sizeof(elevation), &size))
+ {
+ return elevation.TokenIsElevated != 0;
+ }
+ }
+ return false;
}
bool FancyZonesWindowUtils::IsExcludedByUser(const std::wstring& processPath) noexcept
diff --git a/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj b/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj
index 29a985d0d0..5e3406a80a 100644
--- a/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj
+++ b/src/modules/powerrename/PowerRenameUILib/PowerRenameUI.vcxproj
@@ -1,7 +1,7 @@
+
-
true
@@ -171,10 +171,10 @@
-
+
@@ -183,12 +183,12 @@
-
-
+
+
diff --git a/src/modules/powerrename/PowerRenameUILib/packages.config b/src/modules/powerrename/PowerRenameUILib/packages.config
index 6fb8530820..b2166880bb 100644
--- a/src/modules/powerrename/PowerRenameUILib/packages.config
+++ b/src/modules/powerrename/PowerRenameUILib/packages.config
@@ -5,5 +5,5 @@
-
+
\ No newline at end of file
diff --git a/src/modules/powerrename/lib/PowerRenameInterfaces.h b/src/modules/powerrename/lib/PowerRenameInterfaces.h
index 107be6bc86..c25333bd4d 100644
--- a/src/modules/powerrename/lib/PowerRenameInterfaces.h
+++ b/src/modules/powerrename/lib/PowerRenameInterfaces.h
@@ -69,7 +69,6 @@ public:
IFACEMETHOD(GetSelected)(_Out_ bool* selected) = 0;
IFACEMETHOD(PutSelected)(_In_ bool selected) = 0;
IFACEMETHOD(GetId)(_Out_ int *id) = 0;
- IFACEMETHOD(GetIconIndex)(_Out_ int* iconIndex) = 0;
IFACEMETHOD(GetDepth)(_Out_ UINT* depth) = 0;
IFACEMETHOD(PutDepth)(_In_ int depth) = 0;
IFACEMETHOD(ShouldRenameItem)(_In_ DWORD flags, _Out_ bool* shouldRename) = 0;
diff --git a/src/modules/powerrename/lib/PowerRenameItem.cpp b/src/modules/powerrename/lib/PowerRenameItem.cpp
index 8106cab873..c5eccc7112 100644
--- a/src/modules/powerrename/lib/PowerRenameItem.cpp
+++ b/src/modules/powerrename/lib/PowerRenameItem.cpp
@@ -1,6 +1,5 @@
#include "pch.h"
#include "PowerRenameItem.h"
-#include
int CPowerRenameItem::s_id = 0;
@@ -180,16 +179,6 @@ IFACEMETHODIMP CPowerRenameItem::GetId(_Out_ int* id)
return S_OK;
}
-IFACEMETHODIMP CPowerRenameItem::GetIconIndex(_Out_ int* iconIndex)
-{
- if (m_iconIndex == -1)
- {
- GetIconIndexFromPath((PCWSTR)m_path, &m_iconIndex);
- }
- *iconIndex = m_iconIndex;
- return S_OK;
-}
-
IFACEMETHODIMP CPowerRenameItem::GetDepth(_Out_ UINT* depth)
{
*depth = m_depth;
diff --git a/src/modules/powerrename/lib/PowerRenameItem.h b/src/modules/powerrename/lib/PowerRenameItem.h
index 10610306ed..eb3cbcbd70 100644
--- a/src/modules/powerrename/lib/PowerRenameItem.h
+++ b/src/modules/powerrename/lib/PowerRenameItem.h
@@ -27,7 +27,6 @@ public:
IFACEMETHODIMP GetSelected(_Out_ bool* selected);
IFACEMETHODIMP PutSelected(_In_ bool selected);
IFACEMETHODIMP GetId(_Out_ int* id);
- IFACEMETHODIMP GetIconIndex(_Out_ int* iconIndex);
IFACEMETHODIMP GetDepth(_Out_ UINT* depth);
IFACEMETHODIMP PutDepth(_In_ int depth);
IFACEMETHODIMP Reset();
diff --git a/src/runner/Resources.resx b/src/runner/Resources.resx
index 9ac1b8da2f..2f5198b2d1 100644
--- a/src/runner/Resources.resx
+++ b/src/runner/Resources.resx
@@ -122,7 +122,4 @@
Bug report .zip file has been created on your Desktop.
-
- Cannot start PowerToys.Settings process non-elevated, because explorer.exe process is elevated. Consider enabling UAC.
-
diff --git a/src/runner/settings_window.cpp b/src/runner/settings_window.cpp
index 678a88fdbd..5d84d6847d 100644
--- a/src/runner/settings_window.cpp
+++ b/src/runner/settings_window.cpp
@@ -11,7 +11,6 @@
#include "restart_elevated.h"
#include "UpdateUtils.h"
#include "centralized_kb_hook.h"
-#include "Generated Files/resource.h"
#include
#include
@@ -21,7 +20,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -199,6 +197,67 @@ void receive_json_send_to_main_thread(const std::wstring& msg)
dispatch_run_on_main_ui_thread(dispatch_received_json_callback, copy);
}
+// Try to run the Settings process with non-elevated privileges.
+BOOL run_settings_non_elevated(LPCWSTR executable_path, LPWSTR executable_args, PROCESS_INFORMATION* process_info)
+{
+ HWND hwnd = GetShellWindow();
+ if (!hwnd)
+ {
+ return false;
+ }
+
+ DWORD pid;
+ GetWindowThreadProcessId(hwnd, &pid);
+
+ winrt::handle process{ OpenProcess(PROCESS_CREATE_PROCESS, FALSE, pid) };
+ if (!process)
+ {
+ return false;
+ }
+
+ SIZE_T size = 0;
+ InitializeProcThreadAttributeList(nullptr, 1, 0, &size);
+ auto pproc_buffer = std::unique_ptr{ new (std::nothrow) char[size] };
+ auto pptal = reinterpret_cast(pproc_buffer.get());
+ if (!pptal)
+ {
+ return false;
+ }
+
+ if (!InitializeProcThreadAttributeList(pptal, 1, 0, &size))
+ {
+ return false;
+ }
+
+ if (!UpdateProcThreadAttribute(pptal,
+ 0,
+ PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
+ &process,
+ sizeof(process),
+ nullptr,
+ nullptr))
+ {
+ return false;
+ }
+
+ STARTUPINFOEX siex = { 0 };
+ siex.lpAttributeList = pptal;
+ siex.StartupInfo.cb = sizeof(siex);
+
+ BOOL process_created = CreateProcessW(executable_path,
+ executable_args,
+ nullptr,
+ nullptr,
+ FALSE,
+ EXTENDED_STARTUPINFO_PRESENT,
+ nullptr,
+ nullptr,
+ &siex.StartupInfo,
+ process_info);
+ g_isLaunchInProgress = false;
+ return process_created;
+}
+
DWORD g_settings_process_id = 0;
void run_settings_window(bool show_oobe_window, bool show_scoobe_window, std::optional settings_window)
@@ -296,24 +355,13 @@ void run_settings_window(bool show_oobe_window, bool show_scoobe_window, std::op
if (is_process_elevated())
{
- const bool explorer_is_elevated = is_process_of_window_elevated(GetShellWindow());
- if (explorer_is_elevated)
+ auto res = RunNonElevatedFailsafe(executable_path, executable_args, get_module_folderpath());
+ process_created = res.has_value();
+ if (process_created)
{
- MessageBoxW(nullptr,
- GET_RESOURCE_STRING(IDS_CANNOT_LAUNCH_SETTINGS_NONELEVATED).c_str(),
- L"PowerToys",
- MB_OK | MB_ICONERROR);
- }
- else
- {
- auto res = RunNonElevatedFailsafe(executable_path, executable_args, get_module_folderpath());
- process_created = res.has_value();
- if (process_created)
- {
- process_info.dwProcessId = res->processID;
- process_info.hProcess = res->processHandle.release();
- g_isLaunchInProgress = false;
- }
+ process_info.dwProcessId = res->processID;
+ process_info.hProcess = res->processHandle.release();
+ g_isLaunchInProgress = false;
}
}
diff --git a/src/settings-ui/Settings.UI/GlobalSuppressions.cs b/src/settings-ui/Settings.UI/GlobalSuppressions.cs
index 7bb4f5d3b8..e1bb2c7596 100644
--- a/src/settings-ui/Settings.UI/GlobalSuppressions.cs
+++ b/src/settings-ui/Settings.UI/GlobalSuppressions.cs
@@ -73,3 +73,8 @@ using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "Not part of the project. WindowsAppSDK file.", Scope = "type", Target = "~T:Microsoft.WindowsAppSDK.Runtime.Packages.Singleton")]
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1516:Elements should be separated by blank line", Justification = "Not part of the project. WindowsAppSDK file.", Scope = "type", Target = "~T:Microsoft.WindowsAppSDK.Runtime.Packages.Singleton")]
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1516:Elements should be separated by blank line", Justification = "Not part of the project. WindowsAppSDK file.", Scope = "type", Target = "~T:Microsoft.WindowsAppSDK.Runtime.Packages.Main")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1513:Closing brace should be followed by blank line", Justification = "Not part of the project. WindowsAppSDK file.", Scope = "namespaceanddescendants", Target = "Microsoft.WindowsAppSDK.Runtime.Packages")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1516:Elements should be separated by blank line", Justification = "Not part of the project. WindowsAppSDK file.", Scope = "namespaceanddescendants", Target = "Microsoft.WindowsAppSDK.Runtime.Packages")]
+[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1403:File may only contain a single namespace", Justification = "Not part of the project. WindowsAppSDK file.", Scope = "namespaceanddescendants", Target = "Microsoft.WindowsAppSDK.Runtime.Packages.DDLM")]
+[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "Not part of the project. WindowsAppSDK file.", Scope = "namespaceanddescendants", Target = "Microsoft.WindowsAppSDK.Runtime.Packages.DDLM")]
+[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1636:File header copyright text should match", Justification = "Not part of the project. WindowsAppSDK file.", Scope = "module")]
diff --git a/src/settings-ui/Settings.UI/PowerToys.Settings.csproj b/src/settings-ui/Settings.UI/PowerToys.Settings.csproj
index c721a13f83..94631ee13c 100644
--- a/src/settings-ui/Settings.UI/PowerToys.Settings.csproj
+++ b/src/settings-ui/Settings.UI/PowerToys.Settings.csproj
@@ -56,7 +56,7 @@
-
+