【问题标题】:What's the simplest way to execute a method with administrator privileges?以管理员权限执行方法的最简单方法是什么?
【发布时间】:2012-05-14 16:23:01
【问题描述】:

我目前只是在一个新进程中调用我自己的程序:

MyProcessStartInfo.Verb = "runas";
MyProcessStartInfo.Arguments = "MyFlag";

当进程开始时,我会检查标志。如果它在那里 - 我只是执行方法和Close();

但如果可以简单地完成,我宁愿做一些更简约的事情。这可能吗?

编辑:使用 Vista 和 Windows7。

【问题讨论】:

    标签: c# .net process administration


    【解决方案1】:

    您不能提升正在运行的进程。这只是不可能。您正在以正确的方式执行此操作,方法是生成另一个具有更高权限的进程。没有别的办法。

    谢谢。但我在想也许有一种方法可以将方法作为一个新进程来启动。

    您可以创建一个单独的应用程序可执行文件,其中包含您的方法,然后您不需要重新启动您的应用程序。您只需要启动其他进程。

    【讨论】:

    • 谢谢。但我在想也许有一种方法可以将一种方法作为一个新过程来启动。
    • 一个权限为 X 的应用程序生成另一个权限为 X+1 的应用程序将无法在 Windows 7 及更高版本中完成。它仍将在特权 X(不是 X+1)中运行。除非自从我 6 个月前上次尝试之后情况发生了变化。
    【解决方案2】:

    它不是极简的,但你可以使用我从网上来源制作的这个属性。其中一些调用是 pInvoke 的。所以谷歌“pinvoke 方法”来找到它们。

    public static bool IsRunAsAdministrator
    {
        get
        {
            WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent();
            if (windowsIdentity.IsSystem) return true;
    
            WindowsPrincipal windowsPrincipal = new WindowsPrincipal(windowsIdentity);
            if (windowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator))
                return true;
    
            //Vista or higher check
            if (Environment.OSVersion.Version.Major >= 6)
            {
                IntPtr hToken = IntPtr.Zero;
                try
                {
                    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, out hToken))
                        Win32.ThrowLastError();
    
                    TOKEN_ELEVATION_TYPE elevationType;
                    IntPtr pElevationType = Marshal.AllocHGlobal(sizeof(TOKEN_ELEVATION_TYPE));
                    uint dwSize;
    
                    if (!GetTokenInformation(
                        hToken,
                        TOKEN_INFORMATION_CLASS.TokenElevationType,
                        pElevationType,
                        sizeof(TOKEN_ELEVATION_TYPE),
                        out dwSize
                        ))
                        Win32.ThrowLastError();
    
                    elevationType = (TOKEN_ELEVATION_TYPE)Marshal.ReadInt32(pElevationType);
                    Marshal.FreeHGlobal(pElevationType);
    
                    return elevationType == TOKEN_ELEVATION_TYPE.TokenElevationTypeFull;
                }
                finally
                {
                    CloseHandle(hToken);
                }
            }
            else
                return true;
        }
    }
    

    【讨论】:

    • 感谢您的意见,但我想我会坚持使用简单的托管代码。
    • 如果您发现一些简单的东西,请分享。我喜欢在每个操作系统上都适用的东西。
    • +1。检查权限的方法。 @inspiro 确保检查标志位 - 如果您只是在代码具有足够权限时尝试执行操作,则在关闭 UAC 的机器上运行时可能会意外执行操作。
    • @AlexeiLevenkov 我不太明白你的意思。
    • @ispiro,即您的特殊操作是“删除重要文件”,并且您的程序总是在发现它有足够的权限时立即执行它(而不是检查是否指定了“/deleteImportantFile”选项),而不是启动程序的简单事实(在 UAC 的情况下)为管理员帐户关闭)触发删除文件。
    【解决方案3】:

    您可以使用 Windows API LogonUser,然后冒充另一个用户以该用户的身份运行一段代码。不过有一个限制。当 UAC 启用时,LogonUser 会给你受限用户令牌,这意味着模拟用户(甚至管理员)永远不会获得比你已经拥有的更多的权限。此限制不适用于非交互式会话(Windows 服务)。

    这是关于如何在代码中模拟的documentation。此外,您可能会发现this SO question/answer 很有趣。

    【讨论】:

      猜你喜欢
      • 2011-01-02
      • 1970-01-01
      • 2012-12-18
      • 2014-06-25
      • 2018-01-21
      • 2014-10-24
      • 2023-03-31
      • 1970-01-01
      相关资源
      最近更新 更多