如何在需要时提升权限?

问题描述 投票:82回答:6

此问题适用于Windows Vista!

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

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

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

c# .net windows-vista uac privileges
6个回答
56
投票

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

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

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


15
投票

正如有人说there

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

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


13
投票

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

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

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

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

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


4
投票

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

See this question.

Documentation on MSDN.


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

    }
}

1
投票

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.