【问题标题】:How do I force my .NET application to run as administrator?如何强制我的 .NET 应用程序以管理员身份运行?
【发布时间】:2011-02-18 13:52:01
【问题描述】:

在客户端计算机上安装我的程序后,如何强制我的程序在 Windows 7 上以管理员身份运行?

【问题讨论】:

  • 除了 Binary Worrier 写的内容之外,您可能还想编写一些代码来测试您是否具有管理员权限..(这是您要求的吗?)
  • 我不会轻易接受这个任务,你应该验证它实际上需要管理员做什么,看看你是否可以解决它。没有客户会一直乐于在管理员模式下运行应用程序。很多大客户甚至不会考虑这样的应用程序,如果徽标测试对您很重要,它就不会像那样通过。
  • Alex 非常准确。如果可能,仅在必要时提升,否则,组策略、UAC 和许多其他变量会发挥作用。至少,使用 UAC,用户必须在每次运行时授权,而不是仅在执行特定用户操作时授权。
  • 正确的方法是将清单文件嵌入到您的应用程序中。

标签: c# .net windows-7 administrator elevated-privileges


【解决方案1】:

您需要修改嵌入到程序中的清单。这适用于 Visual Studio 2008 及更高版本:项目 + 添加新项目,选择“应用程序清单文件”。将<requestedExecutionLevel> 元素更改为:

 <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

用户在启动程序时会收到UAC 提示。明智地使用;他们的耐心很快就会耗尽。

【讨论】:

  • 如果您在尝试编译时遇到 ClickOnce 错误,请参阅此答案:stackoverflow.com/questions/11023998/…
  • 您的项目也必须设置为使用应用程序清单 - 在项目属性中,检查“应用程序”选项卡并确保“资源”下的“清单:”设置为您的应用程序。清单(或任何您命名的 .manifest 文件)。
  • 在 VS 提示我以管理员模式重新启动之前,我必须重新加载项目。
  • @Alejandro - 是的,UAC 可以被禁用,但是这样的话,应用程序将自动以管理员身份运行(假设您的用户具有管理员权限),因为禁用 UAC 意味着一切都以最高权限运行允许用户。这有点像在抱怨,如果你在门上装了一把花哨的锁,如果把门移开,它就不起作用了。
  • @ErikFunkenbusch 它不会“自动以管理员身份运行”,它将在用户的正常权限下运行(如果用户是管理员,则为管理员,如果用户是标准,则为标准)。依靠这种特殊情况,即使它是默认情况,也是好的程序会像瘟疫一样避免的事情。按照您的类比,花哨的锁固然不错,但设计得当的软件必须预见到整个门都被移除的情况,即使这种情况很少发生。
【解决方案2】:

在清单中添加requestedExecutionLevel 元素只是成功了一半;你必须记住UAC 可以关闭。如果是,您必须执行旧学校方式的检查,如果用户不是管理员
(在您的线程的CurrentPrincipal 上调用IsInRole(WindowsBuiltInRole.Administrator)),则显示错误对话框。

【讨论】:

  • 你也可以使用&lt;requestedExecutionLevel level="highestAvailable" uiAccess="false" /&gt;
  • @MarkKram:highestAvailable 与此有什么关系?问题是关于强制管理员,highestAvailable 比 requireAdministrator 限制更少,并且会让非管理员用户在没有 UAC 提示的情况下启动未提升的应用程序,只有管理员会收到提示...
  • 我不记得确切的细节了,但我认为这取决于您所说的禁用。将“UAC 滑块”一直放在底部与禁用 UAC 不同(Vista 除外)。如果 UAC 完全禁用,则整个完整性级别机制将被禁用,并且只有 2000/XP 中的经典 runas.exe 功能可用。管理员角色检查处理 runas.exe 案例。
  • 我在 Server 2008 R2 上将 EnableLUA 设置为 0,并将自己从管理员组中删除,重新启动,现在一个指定 level="requireAdministrator" 的 exe 运行时没有任何提示
【解决方案3】:

具体步骤如下。

  1. 将应用程序清单文件添加到项目中
  2. 将应用设置更改为“app.manifest”
  3. 将“requestedExecutionLevel”标签更新为requireAdministrator。

请注意,使用此代码您需要关闭 ClickOnce 的安全设置,为此,请进入 Properties -> Security -> ClickOnce Security

【讨论】:

  • New Item... 不是我的安装程序服务项目的选项。我将如何添加应用程序清单?我可以将它添加到我的主项目中,但不是它的安装程序。
【解决方案4】:

我实现了一些代码来手动完成:

using System.Security.Principal;
public bool IsUserAdministrator()
{
    bool isAdmin;
    try
    {
        WindowsIdentity user = WindowsIdentity.GetCurrent();
        WindowsPrincipal principal = new WindowsPrincipal(user);
        isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);
    }
    catch (UnauthorizedAccessException ex)
    {
        isAdmin = false;
    }
    catch (Exception ex)
    {
        isAdmin = false;
    }
    return isAdmin;
}

【讨论】:

  • 这仅检测上下文是否以管理员身份运行,它不会强制应用程序按照 OP 的要求以管理员身份运行
  • 我认为没有任何程序化方式可以强制应用程序提升自己的权限。如果有,那将是相当大的安全风险,不是吗?
  • 虽然您的解决方案很好,但问题不同。 ;)
  • 在此处查看此方法的重构版本stackoverflow.com/a/50186997(主观)
  • 这不能回答问题!
【解决方案5】:

您可以在 EXE 文件中嵌入清单文件,这将导致 Windows(7 或更高版本)始终以管理员身份运行程序。

您可以在 Step 6: Create and Embed an Application Manifest (UAC) (MSDN) 中找到更多详细信息。

【讨论】:

    【解决方案6】:

    在使用 Visual Studio 2008 时,右键单击 Project -&gt; Add New Item,然后选择 Application Manifest File

    在清单文件中,您会找到标签requestedExecutionLevel,您可以将级别设置为三个值:

    &lt;requestedExecutionLevel level="asInvoker" uiAccess="false" /&gt;

    &lt;requestedExecutionLevel level="requireAdministrator" uiAccess="false" /&gt;

    &lt;requestedExecutionLevel level="highestAvailable" uiAccess="false" /&gt;

    要将您的应用程序设置为以管理员身份运行,您必须选择中间的那个。

    【讨论】:

    • 这行得通。但是,在运行CMD应用程序时出现了一个空白的cmd窗口(使用c# cmd app在后台运行一些exe)。
    【解决方案7】:

    另一种仅在代码中执行此操作的方法是检测进程是否像在the answer by @NG. 中那样以管理员身份运行。然后再次打开应用程序并关闭当前应用程序。

    当应用程序在某些条件下运行时(例如将自身安装为服务时)仅需要管理员权限时,我会使用此代码。所以它不需要像其他答案一样一直以管理员身份运行。

    注意以下代码中的NeedsToRunAsAdmin 是一种检测在当前条件下是否需要管理员权限的方法。如果这返回false,代码将不会自行提升。这是这种方法相对于其他方法的主要优势。

    尽管此代码具有上述优点,但它确实需要作为一个新进程重新启动,这并不总是您想要的。

    private static void Main(string[] args)
    {
        if (NeedsToRunAsAdmin() && !IsRunAsAdmin())
        {
            ProcessStartInfo proc = new ProcessStartInfo();
            proc.UseShellExecute = true;
            proc.WorkingDirectory = Environment.CurrentDirectory;
            proc.FileName = Assembly.GetEntryAssembly().CodeBase;
    
            foreach (string arg in args)
            {
                proc.Arguments += String.Format("\"{0}\" ", arg);
            }
    
            proc.Verb = "runas";
    
            try
            {
                Process.Start(proc);
            }
            catch
            {
                Console.WriteLine("This application requires elevated credentials in order to operate correctly!");
            }
        }
        else
        {
            //Normal program logic...
        }
    }
    
    private static bool IsRunAsAdmin()
    {
        WindowsIdentity id = WindowsIdentity.GetCurrent();
        WindowsPrincipal principal = new WindowsPrincipal(id);
    
        return principal.IsInRole(WindowsBuiltInRole.Administrator);
    }
    

    【讨论】:

    • +1 用于纯代码方法。请注意,您需要启用 UAC 才能有机会从非管理员用户以管理员身份使用 runas 启动任何内容,否则它将以当前用户权限静默打开(在 Windows 7 64 位上检查)。据我所知,在禁用 UAC 并且缺少管理员权限的情况下,您唯一能做的就是在适当的时候停止执行。
    【解决方案8】:

    根据

    <requestedExecutionLevel level="highestAvailable" uiAccess="false" />
    

    如果您还没有应用程序清单或不知道如何添加应用程序清单,您将需要添加它。由于某些项目不会自动添加单独的清单文件,请首先转到项目属性,导航到 Application 选项卡并检查以确保您的项目不排除点击底部的清单。

    • 接下来,右键项目
    • 添加新项目
    • 最后,找到并单击应用程序清单文件

    【讨论】:

      【解决方案9】:

      在 Visual Studio 2010 中,右键单击您的项目名称。 点击“查看 Windows 设置”,这将生成并打开一个名为“app.manifest”的文件。 在此文件中,将“asInvoker”替换为“requireAdministrator”,如文件中注释部分所述。

      【讨论】:

      • 这个答案是关于 VB.NET :-) ,而不是一般的 VS 2010。 “添加新项目”的答案是关于 C# 的。在 C++ 中,您可以在项目设置中执行此操作。
      【解决方案10】:

      您可以使用 ClickOnce 安全设置创建清单,然后将其禁用:

      Right click on the Project -> Properties -> Security -> Enable ClickOnce Security Settings
      

      点击后会在项目的属性文件夹下创建一个名为app.manifest的文件,一旦创建,你可以取消选中Enable ClickOnce Security Settings选项

      打开该文件并更改这一行:

      <requestedExecutionLevel level="asInvoker" uiAccess="false" />
      

      到:

       <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
      

      这将使程序需要管理员权限。

      【讨论】:

        【解决方案11】:

        这不会强制申请以管理员身份工作。
        这是answer 的简化版本,由@NG 提供

        public bool IsUserAdministrator()
        {
            try
            {
                WindowsIdentity user = WindowsIdentity.GetCurrent();
                WindowsPrincipal principal = new WindowsPrincipal(user);
                return principal.IsInRole(WindowsBuiltInRole.Administrator);
            }
            catch
            {
                return false;
            }
        }
        

        【讨论】:

        • 这不能回答问题!
        • @Elmue 将您的评论添加到我刚刚重构的原始答案中更合乎逻辑,您可以在我的答案中找到该答案的链接。
        【解决方案12】:

        如果您出于某种原因需要纯代码解决方案,这里有一个独立的类文件。只需在应用程序启动时调用“AdminRelauncher.RelaunchIfNotAdmin()”:

        using System;
        using System.Diagnostics;
        using System.Reflection;
        using System.Security.Principal;
        
        public static class AdminRelauncher
        {
            public static void RelaunchIfNotAdmin()
            {
                if (!RunningAsAdmin())
                {
                    Console.WriteLine("Running as admin required!");
                    ProcessStartInfo proc = new ProcessStartInfo();
                    proc.UseShellExecute = true;
                    proc.WorkingDirectory = Environment.CurrentDirectory;
                    proc.FileName = Assembly.GetEntryAssembly().CodeBase;
                    proc.Verb = "runas";
                    try
                    {
                        Process.Start(proc);
                        Environment.Exit(0);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("This program must be run as an administrator! \n\n" + ex.ToString());
                        Environment.Exit(0);
                    }
                }
            }
        
            private static bool RunningAsAdmin() 
            {
                WindowsIdentity id = WindowsIdentity.GetCurrent();
                WindowsPrincipal principal = new WindowsPrincipal(id);
        
                return principal.IsInRole(WindowsBuiltInRole.Administrator);              }
            }
        

        【讨论】:

          【解决方案13】:

          右键单击您的可执行文件,转到“属性”>“兼容性”并选中“以管理员身份运行此程序”框。

          如果您想为所有用户以管理员身份运行它,请在“更改所有用户的设置”中执行相同的操作。

          【讨论】:

          • 这不能回答问题。 “一旦我的程序安装在客户端计算机上”,而不是“我该怎么做”。
          • 抱歉不清楚。安装程序后,在可执行文件的属性(您的主程序,而不是安装程序)中更改此设置。他确实想强制他的程序以管理员身份运行。
          • 最好在清单中设置管理员要求。我认为它回答了这个问题,但几乎没有。
          • @Joe 公平地说,接受的答案没有回答 OPs 问题,因为需要您重新安装应用程序 exe。这几乎不是“安装我的程序后”的解决方案。如果这个被否决的答案比接受的答案更正确,那么我不明白为什么这个答案有 400 多票。
          • 实际上,它完美地回答了这两个问题。安装后更改清单的可能性不大,并且程序在运行后不应尝试提升其权限 - 在许多环境中 - 这是被称为恶意软件的好方法。在大多数公司中——这个答案是最好的,因为它把责任放在了用户和他们的权限上。我编写了很多代码,一旦投入生产,我就无法“看到”或运行。尽量不要比您自己的安全问题更聪明。
          猜你喜欢
          • 2012-08-08
          • 2010-12-19
          • 2013-06-17
          相关资源
          最近更新 更多