如何在需要时提升权限?

时间:2009-02-21 14:13:34

标签: c# .net windows-vista uac privileges

此问题适用于Windows Vista!

我有一个通常无需管理权限的应用程序。有一项活动确实需要管理权限,但我不想以更高的权限启动应用程序本身,因为我知道大部分时间用户甚至不会使用该功能。

我正在考虑某种方法,通过该方法我可以在某些事件上提升应用程序的权限(例如按下按钮)。例如:

如果用户单击此按钮,则会提示他使用UAC对话框或同意。我怎么能这样做?

6 个答案:

答案 0 :(得分:56)

我认为不可能提升当前正在运行的流程。据我所知,它内置于Windows Vista中,启动时会为进程提供管理员权限。如果您查看使用UAC的各种程序,您应该看到每次需要执行管理操作时它们实际上都会启动一个单独的进程(任务管理器是一个,Paint.NET是另一个,后者实际上是.NET应用程序) )。

此问题的典型解决方案是在启动提升的进程时指定命令行参数(abatishchev的建议是一种方法),以便启动的进程只知道显示某个对话框,然后在此之后退出行动已经完成。因此,用户几乎不会注意到新进程已经启动然后退出,而是看起来好像在同一个应用程序中打开了一个新对话框(特别是如果你有一些hackery来制作主窗口)提升过程父进程的子进程)。如果您不需要用于提升访问的UI,那就更好了。

有关Vista上UAC的完整讨论,我建议你看一下this very through article这个主题(代码示例是用C ++编写的,但我怀疑你需要使用WinAPI和P / Invoke来完成大部分工作。 C#中的东西无论如何)。希望你现在至少可以看到正确的方法,尽管设计一个符合UAC标准的程序远非微不足道......

答案 1 :(得分:15)

据说there

Process.StartInfo.UseShellExecute = true;
Process.StartInfo.Verb = "runas";

将以管理员身份运行该过程,以便通过注册表执行您需要的任何操作,但以正常权限返回您的应用。

答案 2 :(得分:13)

以下MSDN知识库文章981778描述了如何“自我提升”应用程序:

http://support.microsoft.com/kb/981778

它包含Visual C ++,Visual C#,Visual Basic.NET中的可下载示例。

这种方法绕过了启动单独进程的需要,但实际上它是重新启动的原始应用程序,以提升用户身份运行。然而,在某些情况下,这可能仍然非常有用,因为在单独的可执行文件中复制代码是不切实际的。

要删除高程,您需要退出该应用程序。

答案 3 :(得分:4)

您需要一个UAC名字对象并将代码作为COM对象提升运行。

See this question.

Documentation on MSDN.

答案 4 :(得分:2)

也许有人派上用场这个简单的例子:

using System;
using System.Linq;
using System.Reflection;
using System.Diagnostics;
using System.Security.Principal;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    internal static class Program
    {
        private class Form1 : Form
        {
            internal Form1()
            {
                var button = new Button{ Dock = DockStyle.Fill };
                button.Click += (sender, args) => RunAsAdmin();
                Controls.Add(button);

                ElevatedAction();
            }
        }

        [STAThread]
        internal static void Main(string[] arguments)
        {
            if (arguments?.Contains("/run_elevated_action") == true)
            {
                ElevatedAction();
                return;
            }

            Application.Run(new Form1());
        }

        private static void RunAsAdmin()
        {
            var path = Assembly.GetExecutingAssembly().Location;
            using (var process = Process.Start(new ProcessStartInfo(path, "/run_elevated_action")
            {
                Verb = "runas"
            }))
            {
                process?.WaitForExit();
            }
        }

        private static void ElevatedAction()
        {
            MessageBox.Show($@"IsElevated: {IsElevated()}");
        }

        private static bool IsElevated()
        {
            using (var identity = WindowsIdentity.GetCurrent())
            {
                var principal = new WindowsPrincipal(identity);

                return principal.IsInRole(WindowsBuiltInRole.Administrator);
            }
        }

    }
}

答案 5 :(得分:1)

我知道这是一篇旧帖子,但这是对任何遇到MarcP建议的人的回应。他引用的msdn帖子确实重新启动了所有代码示例中的应用程序。代码示例使用其他建议中已提出的runas动词。

我下载了代码以确保,但这是来自最初的msdn文章:

  

4。单击是以批准高程。然后,原始的应用程序       重新启动,以提升的管理员身份运行    5.关闭应用程序。