Skip to content

Commit

Permalink
update: if UAC requested demo
Browse files Browse the repository at this point in the history
  • Loading branch information
emako committed Jul 16, 2024
1 parent 31dd036 commit 7664147
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 8 deletions.
36 changes: 30 additions & 6 deletions demo/PresentMon.SampleWPF/MaskWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using CommunityToolkit.Mvvm.ComponentModel;
using PresentMonFps;
using System.Diagnostics;
using System.Windows;
using System.Windows.Interop;
using Vanara.PInvoke;
Expand All @@ -25,19 +26,42 @@ private void OnLoaded(object sender, RoutedEventArgs e)
uint pid = FpsInspector.GetProcessIdByName("YuanShen.exe");
nint targetHWnd = FpsInspector.GetMainWindowHandle(pid);

if (pid == 0 || targetHWnd == 0)
{
throw new Exception("Process is not running.");
}

_ = User32.GetClientRect(hWnd, out RECT rect);
_ = User32.SetParent(hWnd, targetHWnd);
_ = User32.GetClientRect(targetHWnd, out RECT targetRect);
var succ = User32.SetParent(hWnd, targetHWnd);
RECT targetRect = default;
bool isUACRequested = FpsInspector.IsRunAsAdmin();
bool isTargetUACRequested = false;

if (succ != 0)
{
_ = User32.GetClientRect(targetHWnd, out targetRect);

float x = DpiHelper.GetScale(targetHWnd).X;
_ = User32.SetWindowPos(hWnd, IntPtr.Zero, 0, 0, (int)(targetRect.Width * x), (int)(targetRect.Height * x), User32.SetWindowPosFlags.SWP_SHOWWINDOW);
float x = DpiHelper.GetScale(targetHWnd).X;
_ = User32.SetWindowPos(hWnd, IntPtr.Zero, 0, 0, (int)(targetRect.Width * x), (int)(targetRect.Height * x), User32.SetWindowPosFlags.SWP_SHOWWINDOW);
}
else
{
nint targetProcessHandle = FpsInspector.GetProcessHandle(pid);

isTargetUACRequested = targetProcessHandle == IntPtr.Zero || FpsInspector.IsRunAsAdmin(targetProcessHandle);
_ = User32.SetParent(hWnd, IntPtr.Zero);
Debug.WriteLine($"Failed to SetParent {(isTargetUACRequested ? ", the Administrator UAC is requested" : string.Empty)}.");
}

_ = Task.Run(async () =>
{
await FpsInspector.StartForeverAsync(new FpsRequest(pid), (result) =>
{
float x = DpiHelper.GetScale(targetHWnd).X;
_ = User32.SetWindowPos(hWnd, IntPtr.Zero, 0, 0, (int)(targetRect.Width * x), (int)(targetRect.Height * x), User32.SetWindowPosFlags.SWP_SHOWWINDOW);
if (!isTargetUACRequested || (isTargetUACRequested && isUACRequested))
{
float x = DpiHelper.GetScale(targetHWnd).X;
_ = User32.SetWindowPos(hWnd, IntPtr.Zero, 0, 0, (int)(targetRect.Width * x), (int)(targetRect.Height * x), User32.SetWindowPosFlags.SWP_SHOWWINDOW);
}
Fps = $"{result.Fps:0}";
});
});
Expand Down
33 changes: 33 additions & 0 deletions src/FpsInspector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,29 @@ public static nint GetMainWindowHandle(uint processId)
return mainWindowHandle;
}

public static nint GetProcessHandle(uint processId)
{
try
{
nint processHandle = IntPtr.Zero;

Process? p = Process.GetProcesses().Where(p => p.Id == processId).FirstOrDefault();

if (p != null)
{
return p.Handle;
}

return processHandle;
}
catch (Exception e)
{
_ = e.Message;
}

return IntPtr.Zero;
}

public static async Task<uint> GetProcessIdByNameAsync(string processName)
{
return await Task.Run(() => Kernel32.GetProcessIdByName(processName));
Expand Down Expand Up @@ -210,6 +233,16 @@ void OnFpsReceived(double fps)
throw new FpsInspectorException(e.Message);
}
}

public static bool IsRunAsAdmin()
{
return AdvApi32.IsRunAsAdmin();
}

public static bool IsRunAsAdmin(nint hWnd)
{
return AdvApi32.IsRunAsAdmin(hWnd);
}
}

public sealed class FpsRequest(uint targetPid)
Expand Down
9 changes: 7 additions & 2 deletions src/Natives/AdvApi32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,18 @@ public struct EVENT_DESCRIPTOR_DECL(ushort id, byte version, byte channel, byte
public static extern uint ControlTrace(ulong sessionHandle, string sessionName, ref EVENT_TRACE_PROPERTIES properties, EVENT_TRACE_CONTROL ControlCode);

public static bool IsRunAsAdmin()
{
return IsRunAsAdmin(Kernel32.GetCurrentProcess());
}

public static bool IsRunAsAdmin(nint hWnd)
{
nint tokenHandle = IntPtr.Zero;
try
{
if (!OpenProcessToken(Kernel32.GetCurrentProcess(), TOKEN_QUERY, out tokenHandle))
if (!OpenProcessToken(hWnd, TOKEN_QUERY, out tokenHandle))
{
throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
throw new Win32Exception(Marshal.GetLastWin32Error());
}

GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenElevation, IntPtr.Zero, 0, out uint tokenInfoLength);
Expand Down

0 comments on commit 7664147

Please sign in to comment.