如何强制我的 .NET 应用程序以管理员身份运行?

How do I force my .NET application to run as administrator?

提问人:Gold 提问时间:5/12/2010 最后编辑:Arsen KhachaturyanGold 更新时间:4/12/2022 访问量:608733

问:

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

C# .NET Windows-7 管理员 提升权限

评论

3赞 lexu 5/12/2010
除了 Binary Worrier 编写的内容外,您可能还想编写一些代码来测试您是否具有管理员权限。(这是你要的吗?
43赞 Alex 5/12/2010
不过,我不会掉以轻心,您应该验证它实际需要管理员做什么,看看是否可以解决它。没有客户会乐于一直以管理员模式运行应用程序。许多大客户甚至不会考虑这样的应用程序,如果徽标测试对您很重要,它就不会像那样通过。
3赞 Anthony Mason 11/12/2016
亚历克斯说得很对。如果可能,请仅在必要时提升,否则,组策略、UAC 和许多其他变量将发挥作用。至少,使用 UAC,用户必须在每次运行时进行授权,而不是仅在执行特定用户操作时进行授权。
0赞 Elmue 10/4/2019
正确的方法是将清单文件嵌入到应用程序中。

答:

42赞 David 5/12/2010 #1

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

有关详细信息,请参阅步骤 6:创建和嵌入应用程序清单 (UAC) (MSDN)。

1269赞 Hans Passant 5/12/2010 #2

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

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

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

评论

42赞 SSS 12/2/2013
如果在尝试编译时遇到 ClickOnce 错误,请参阅以下答案:stackoverflow.com/questions/11023998/...
25赞 Victor Chelaru 4/12/2016
你的项目也必须设置为使用应用清单 - 在项目属性中,选中“应用程序”选项卡,并确保“资源”下的“清单:”设置为你的 app.manifest(或你命名的 .manifest 文件)。
7赞 Jon 3/1/2017
我必须重新加载项目,然后 VS 会提示我以管理员模式重新启动。
3赞 Erik Funkenbusch 5/5/2018
@Alejandro - 是的,可以禁用 UAC,但此时,应用将自动以管理员身份运行(假设用户具有管理员权限),因为禁用 UAC 意味着所有内容都以允许用户的最高权限运行。这有点像抱怨,如果你在门上安装了一把花哨的锁,如果门被拆除,它就不起作用了。
4赞 Alejandro 5/6/2018
@ErikFunkenbusch 它不会“以管理员身份自动运行”,它将在用户的正常权限下运行(如果用户是管理员,则为 admin,如果用户是标准,则为 standard)。依赖这种特殊情况,即使它是默认的,也是好的程序会像瘟疫一样避免的。按照你的类比,花哨的锁很好,但设计得当的软件必须预测到整个门被移除的情况,即使这种情况很少发生。
162赞 Anders 5/13/2010 #3

将元素添加到清单只是成功的一半;您必须记住,UAC 可以关闭。如果是,则必须以老式方式执行检查,如果用户不是管理员
,则必须弹出错误对话框(在线程上调用IsInRole(WindowsBuiltInRole.Administrator))。
requestedExecutionLevelCurrentPrincipal

评论

23赞 Mark Kram 8/14/2011
你也可以使用<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
18赞 Anders 9/18/2013
@MarkKram:highestAvailable与此有什么关系?问题是关于强制管理员,highestAvailable 比 requireAdministrator 的限制更少,并且会让非管理员用户在没有 UAC 提示的情况下启动未提升的应用程序,只有管理员才会收到提示......
0赞 Anders 8/20/2019
我不记得确切的细节了,但我认为这取决于你所说的禁用是什么意思。将“UAC 滑块”一直放在底部与禁用 UAC 不同(Vista 除外)。如果完全禁用 UAC,则禁用整个完整性级别机制,并且只有 2000/XP 中的经典 runas.exe 功能可用。管理员角色检查处理 runas.exe 大小写。
1赞 Tal Aloni 8/21/2019
我在 Server 2008 R2 上将 EnableLUA 设置为 0,并将自己从 Administrators 组中删除,重新启动,现在指定 level=“requireAdministrator” 的 exe 在没有任何提示的情况下运行
11赞 Evolved 9/7/2011 #4

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

评论

7赞 Philm 8/9/2013
这个答案是关于 VB.NET :-) ,而不是一般的 VS 2010。“添加新项”答案是关于 C# 的。在 C++ 中,您可以在项目设置中执行此操作。
19赞 Rashad Maqsood 3/6/2013 #5

在 Visual Studio 2008 上工作时,右键单击,然后选择 。Project -> Add New ItemApplication Manifest File

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

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

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

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

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

评论

0赞 W.M. 10/19/2017
这行得通。但是,它在运行 CMD 应用程序时出现一个空白的 cmd 窗口(使用 c# cmd 应用程序在后台运行一些 exe)。
12赞 Justin Mcconnell 3/17/2013 #6

根据

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

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

  • 接下来,右键单击项目
  • 添加新项目
  • 最后,找到并单击应用程序清单文件
74赞 NG. 8/30/2013 #7

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

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;
}

评论

54赞 Matt Wilko 12/5/2013
这仅检测上下文是否以管理员身份运行,它不会按照 OP 的要求以管理员身份运行应用程序
6赞 Mark Richman 8/19/2014
我不认为有任何程序化方法可以强制应用程序提升自己的烫发率。如果有的话,那将是相当大的安全风险,不是吗?
7赞 Yash 7/26/2015
虽然你的解决方案很好,但问题是不同的。;)
0赞 Hakan Fıstık 12/3/2018
在此处查看此方法的重构版本 stackoverflow.com/a/50186997(主观)
0赞 Elmue 10/4/2019
这并不能回答问题!
16赞 TheLethalCoder 1/12/2017 #8

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

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

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

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

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赞 reallynice 8/9/2019
+1 表示仅代码方法。请注意,您需要启用 UAC 才能有机会从非管理员用户以管理员身份启动任何内容,否则它将以当前用户权限静默打开(在 Windows 7 64 位上检查)。据我所知,在禁用 UAC 且缺少管理员权限的情况下,您唯一能做的就是在适当的时候停止执行。runas
0赞 djk 4/11/2023
这也是唯一传递原始命令行参数的答案。+1
144赞 Hassan Rahman 5/12/2017 #9

详细步骤如下。

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

Adding file in Solution

Select Application Manifest File

Select Manifest option

Update Manifest file

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

评论

1赞 HackSlash 3/27/2020
New Item...不是我的安装程序服务项目中的一个选项。如何添加应用清单?我可以将它添加到我的主项目中,但不能将其添加到安装程序中。
11赞 Yochai Timmer 2/14/2018 #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" />

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

7赞 Hakan Fıstık 5/5/2018 #11

这不会强制应用程序以管理员身份工作。
这是上面这个答案的简化版本,由@NG

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

评论

5赞 Elmue 10/3/2019
这并不能回答问题!
0赞 Hakan Fıstık 10/3/2019
@Elmue将您的评论添加到我刚刚重构的原始答案中更合乎逻辑,您可以在我的答案中找到该答案的链接。
9赞 Gaspa79 3/4/2021 #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);
    }
}