From 46a158712abf5fa06401c8288fa8e68e1e3a3348 Mon Sep 17 00:00:00 2001 From: Gerardo Grignoli Date: Mon, 27 May 2024 23:16:51 -0300 Subject: [PATCH] feat: Improve UAC prompt handling by focusing the UAC window, useful when UAC set as Do Not Dim. Fixes #85 --- src/gsudo/Helpers/ServiceHelper.cs | 9 ++++++ src/gsudo/Helpers/UACWindowFocusHelper.cs | 38 +++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 src/gsudo/Helpers/UACWindowFocusHelper.cs diff --git a/src/gsudo/Helpers/ServiceHelper.cs b/src/gsudo/Helpers/ServiceHelper.cs index bff39a0d..c95eed90 100644 --- a/src/gsudo/Helpers/ServiceHelper.cs +++ b/src/gsudo/Helpers/ServiceHelper.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Security; using System.Security.Principal; +using System.Threading; using System.Threading.Tasks; namespace gsudo.Helpers @@ -175,13 +176,21 @@ internal static SafeProcessHandle StartService(int? allowedPid, TimeSpan? cacheD else { if (SecurityHelper.IsMemberOfLocalAdmins() && InputArguments.GetIntegrityLevel() >= IntegrityLevel.High) + { + // UAC Popup doesnt always have focus, so we try to bring it to the front. + new Thread(UACWindowFocusHelper.FocusUacWindow).Start(); + ret = ProcessFactory.StartElevatedDetached(ownExe, commandLine, !InputArguments.Debug).GetSafeProcessHandle(); + } else ret = ProcessFactory.StartDetached(ownExe, commandLine, null, !InputArguments.Debug).GetSafeProcessHandle(); } } else { + // UAC Popup doesnt always have focus, so we try to bring it to the front. + new Thread(UACWindowFocusHelper.FocusUacWindow).Start(); + ret = ProcessFactory.StartElevatedDetached(ownExe, commandLine, !InputArguments.Debug).GetSafeProcessHandle(); } diff --git a/src/gsudo/Helpers/UACWindowFocusHelper.cs b/src/gsudo/Helpers/UACWindowFocusHelper.cs new file mode 100644 index 00000000..f2a98519 --- /dev/null +++ b/src/gsudo/Helpers/UACWindowFocusHelper.cs @@ -0,0 +1,38 @@ +using gsudo.Native; +using System; +using System.Runtime.InteropServices; + +namespace gsudo.Helpers +{ + internal class UACWindowFocusHelper + { + [DllImport("user32.dll", SetLastError = true)] + private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); + + internal static void FocusUacWindow() + { + try + { + for (int i = 0; i < 10; i++) + { + // Wait a moment to allow the UAC prompt to appear + System.Threading.Thread.Sleep(100); + + // Find the UAC window + string classname = "Credential Dialog Xaml Host"; // Found using Visual Studio spyxx_amd64.exe, this is the value for Windows 10 & 11. + IntPtr uacWindow = FindWindow(classname, null); + if (uacWindow != IntPtr.Zero) + { + // Set focus to the UAC window + WindowApi.SetForegroundWindow(uacWindow); + return; + } + } + } + catch (Exception ex) + { + Logger.Instance.Log("Error searching for UAC Window: " + ex.ToString(), LogLevel.Debug); + } + } + } +}