Process.GetProcesses() WHERE process.IsElevated?

本文关键字:process IsElevated WHERE GetProcesses Process | 更新日期: 2023-09-27 18:12:17

我想在非管理用户登录时监视机器上运行的提升进程。

基本上,我想从c#中运行以下组成的代码:
var elevatedWindows = Process.GetProcesses().Where(p => p.IsElevated || p.ChildWindows.Any(cw => cw.IsElevated));

到目前为止,我找到的唯一能给我提供我想要的信息的东西似乎是.NET System.Diagnostics.Process类中的一个BUG,如下所述:

http://www.codeproject.com/Articles/302856/Bugs-in-System-Diagnostics-Process-Class

如果我理解正确,文章说,如果我的程序没有以提升的权限运行,如果您试图获得提升进程的StartTimeHasExited属性,它将生成一个WIN32异常,NativeErrorCode等于5。我觉得这可能是我的问题的一个简单的解决方案-尝试从非提升程序获得StartTimeHasExited,如果它产生该错误,它是一个提升的过程。

问题是,我似乎不能让这个可靠地工作,HasExited错误不可靠时,我手动右键单击记事本,选择"运行为管理员",并使用GetProcessesByName("notepad")

更麻烦的是我不能隔离单独的资源管理器Windows。Explorer.exe始终运行,并且可以被提升,但是即使它在没有提升的情况下运行,您仍然可以通过多种不同的方式手动启动进程,这些方式都不会影响父Explorer.exe进程。

所以我想我需要从派生的进程中找到窗口处理程序,或者他们的子线程,并以某种方式看看窗口是否被提升?

Process.GetProcesses() WHERE process.IsElevated?

我不太明白你说的"高架窗口"是什么意思。提升的是过程,而不是窗口。启动一个新的资源管理器视图会生成一个新的进程。

也就是说,您可以使用Interop来确定进程是否被提升:

  • 调用OpenProcess获取进程句柄
  • 调用OpenProcessToken打开与您的进程关联的访问令牌
  • 然后使用GetTokenInformation
代码:

public enum ElevationType
{
    Default = 1,
    Full = 2,
    Limited = 3
}
// Do add some exception handling...etc.
public static ElevationType GetProcessElevationTypeByTokenHandle(IntPtr hTok)
{
    if (hTok.IsNotNull)
    {
        // Get token information struct length
        // See https://msdn.microsoft.com/en-us/library/windows/desktop/aa379626(v=vs.85).aspx for constants
        int ret = 0;
        GetTokenInformation(hTok, TokenInformationClass.TokenElevationType, IntPtr.Zero, 0, ret);
        IntPtr tokenInformation = Marshal.AllocHGlobal(ret);
        // Get token information struct
        // With then TokenElevationType constant, it will returns a TOKEN_ELEVATION_TYPE value
        // See https://msdn.microsoft.com/en-us/library/windows/desktop/bb530718(v=vs.85).aspx
        GetTokenInformation(hTok, TokenInformationClass.TokenElevationType, tokenInformation, ret, null);
        // Get a valid structure
        var value = Marshal.ReadInt32(tokenInformation, 0);
        Marshal.FreeHGlobal(tokenInformation);
        return (ElevationType)value;
    }
    else
    {
        return ElevationType.Default;
    }
}