C#实现以管理员身份运行程序的最全总结(WinForm/WPF)

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天, 点击查看活动详情

程序使用过程中经常遇到需要管理员权限运行才能执行的情况,如操作注册表、系统文件或配置文件等。

以管理员权限运行程序的最简单方式,是右键程序,选择“以管理员权限运行”。

但,如果打开时,默认以系统管理员权限运行,将会很方便。本篇将对几种实现管理员权限运行的方式进行总结,希望足够全。

方法一【ClickOnce生成清单文件】

  • Visual studio 中,解决方案资源管理器下,右键项目>属性,在 安全性 下,勾选 启用ClickOnce安全设置
  • app.manifest 文件会出现在项目名下面的 属性 目录中。
  • 双击打开,并找到代码 <requestedExecutionLevel level="asInvoker" uiAccess="false" /> ,将属性 level 的值改为 requireAdministrator

    文件中对UAC控制(User Account Control)已经进行了说明

    修改后保存即可。

  • asInvoker : 应用程序以当前的权限运行。
  • highestAvailable: 以当前用户可以获得的最高权限运行。
  • requireAdministrator: 请求以系统管理员权限运行。
  • 重新打开项目 属性 > 安全性 ,将 启用ClickOnce安全设置 的勾选取消。
  • 启用ClickOnce安全设置 的情况下: 如果debug启动,程序会提示不可用于VS进程。VS将不能进行安全调试。

    如果直接生成,会报错 ClickOnce 不支持请求执行级别“requireAdministrator”。 RegisterUse

    因此,需要取消勾选 启用ClickOnce安全设置

  • 执行 调试>启动,会提示相应权限运行。
  • 即,要管理员权限运行当前程序,需要vs也是管理员权限打开。

  • 重新编译生成exe程序,双击运行,会 请求管理员权限 运行。
  • 方法二【直接添加清单文件】

    项目下添加 项目清单 文件。

  • 右键项目>添加>新建项>选择 应用程序清单文件
  • 此时在项目下会生成 app.manifest 文件。其内容和修改与上面的设置相同
  • 这样就不用修改 启用ClickOnce安全设置

    方法三【判断程序自身是否管理员权限运行,并使用Process管理员重新启动自身】

    通过判断当前运行程序的权限是管理员还是非管理员,决定是否请求管理员权限运行程序。这对于将程序安装到C盘后,需要管理员权限操作,其他盘则不需要管理员权限,会显得比较灵活。

    通过修改 Program 文件,借助System.Diagnostics.Process.Start()以应用程序进程的方式重新以管理员权限打开程序(只有当前用户为管理员时才会直接运行)。

    static class Program
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            //获取当前登陆的windows用户
            //获取当前Windows用户的WindowsIdentity对象
            System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent();
            //创建可以代码访问的windows组成员对象
            System.Security.Principal.WindowsPrincipal principal = new System.Security.Principal.WindowsPrincipal(identity);
            //判断是否为管理员
            if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator))
                //如果是管理员则直接运行
                Application.Run(new Form1());
                //创建启动对象
                //指定启动进程时的信息
                System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
                startInfo.UseShellExecute = true;
                startInfo.WorkingDirectory = Environment.CurrentDirectory;//设置当前工作目录的完全路径
                startInfo.FileName = Application.ExecutablePath;//获取当前执行文件的路径
                //设置启动动作,确保以管理员权限运行
                startInfo.Verb = "runas";
                    System.Diagnostics.Process.Start(startInfo);
                catch (Exception)
                    return;
                //退出当前,使用新打开的程序
                Application.Exit();
            //Application.Run(new Form1());
    

    方法四【修改程序属性的兼容性设置】

    直接修改程序文件的属性。

    右键exe文件,属性>兼容性下,设置以管理员身份运行此程序

    附:判断程序当前运行是管理员权限还是非管理员权限

    public static bool IsAdministrator()
        WindowsIdentity identity = WindowsIdentity.GetCurrent();
        WindowsPrincipal principal = new WindowsPrincipal(identity);
        return principal.IsInRole(WindowsBuiltInRole.Administrator);
    

    附:通过Process.Start()启动程序时接收命令行或输入参数

    上面使用Process.Start()以管理员方式重新启动自身程序时,没有考虑到Main入口方法的输入参数的传递问题。借助ProcessStartInfo.Arguments可以在启动程序时,传入启动参数。

    /// <summary>
    /// 应用程序的主入口点。
    /// </summary>
    [STAThread]
    static void Main(string[] Args)
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        //获取当前登陆的windows用户
        //获取当前Windows用户的WindowsIdentity对象
        WindowsIdentity identity = WindowsIdentity.GetCurrent();
        //创建可以代码访问的windows组成员对象
        WindowsPrincipal principal = new WindowsPrincipal(identity);
        //判断是否为管理员
        if (principal.IsInRole(WindowsBuiltInRole.Administrator))
            //如果是管理员则直接运行
            if (Args.Length>0)//判断是否输入参数
                Application.Run(new Form1(Args));
                Application.Run(new Form1());
            //创建启动对象
            //指定启动进程时的信息
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.UseShellExecute = true;
            startInfo.WorkingDirectory = Environment.CurrentDirectory;//设置当前工作目录的完全路径
            //设置运行文件
            startInfo.FileName = Application.ExecutablePath;//获取当前执行文件的路径
            //设置启动参数
            if (Args.Length>0)
                //获取或设置启动应用程序时的邮政命令行自变量
                startInfo.Arguments = String.Join(" ", Args);
            //设置启动动作,确保以管理员权限运行
            startInfo.Verb = "runas";
                Process.Start(startInfo);
            catch (Exception)
                MessageBox.Show("启动失败!");
                return;
            //退出当前,使用新打开的程序
            Application.Exit();
    

    ProcessStartInfo.Verb = "runas"以管理员权限启动进程来说,可以实现管理员权限运行另一个程序,或,启动另一个进程。

  • C# WinForm判断Win7下是否是管理员身份运行
  • C#程序以管理员权限运行
  • C# 以管理员身份运行WinForm程序
  • 分类:
    后端
  •