【问题标题】:Giving application elevated UAC为应用程序提供提升的 UAC
【发布时间】:2011-09-18 18:22:57
【问题描述】:

我有一个需要 UAC 提升的应用程序。

我有代码可以让我给它,但应用程序打开两次..这是问题..

所以这是Form1中的代码:

 public Form1()
    {
        InitializeComponent();

        WindowsPrincipal pricipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
        bool hasAdministrativeRight = pricipal.IsInRole(WindowsBuiltInRole.Administrator);           

        if (!hasAdministrativeRight)
        {
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.UseShellExecute = true;
            startInfo.WorkingDirectory = Environment.CurrentDirectory;
            startInfo.FileName = Application.ExecutablePath;
            startInfo.Verb = "runas";
            try
            {
                Process p = Process.Start(startInfo);
            }
            catch (System.ComponentModel.Win32Exception ex)
            {
                return;
            }

        }

    }

这是代码programs.cs

       static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

在调试时我发现它首先执行

进程 p = Process.Start(startInfo);

打开应用程序 UAC 提升对话框,然后打开应用程序

但后来它去了

Application.Run(new Form1());

在 main() 中并再次打开应用程序。

我不想让它再次打开应用程序...

我是新手,有什么我做错了吗?我需要在 UAC 打开后关闭它吗?

谢谢

【问题讨论】:

  • 所以这对我来说很好......因为我是从 VS 运行的,它要求我重新启动应用程序,我这样做了。然后它问我它将在我的计算机中进行更改..但我在信息中看到这些更改只会影响当前的应用程序。所以我允许了。现在这个应用程序已经提升了 UAC 权限。我运行了另一个应用程序,发现我不是管理员,这是需要的。

标签: c# asp.net winforms uac


【解决方案1】:

您无需干预所有这些以确保您的应用程序始终以提升的权限运行。您可以简单地add an application manifest 指示 Windows 运行提升的应用程序,并且 UAC 提示将出现而无需您编写任何代码。

有一个相关问题的答案也描述了如何在此处添加清单:How can I embed an application manifest into an application using VS2008?

【讨论】:

  • 我尝试过使用它,但现在当我从 VS 运行应用程序时,它要求我“在不同的凭据下重新启动”,如果我这样做,它想对计算机进行更改..??这安全吗?我的意思是我不想只为这个应用程序永久地这样做..
  • 应用程序需要管理权限,正如您要求的那样。
  • 因为您很可能没有将 Visual Studio 作为提升的进程运行。由于您是从 Visual Studio 启动应用程序,因此需要提升 Visual Studio 才能启动提升的进程。
  • 我们随时为您提供帮助,不用担心。 =)
  • 这是一个great answer,其中包含有关如何设置应用程序清单以获得提升权限的非常具体的说明。
【解决方案2】:

提升您的权限总是会启动一个新进程。除了首先通过将应用程序设置为需要管理权限来提升权限之外,没有其他办法。您可以做的是在提升的进程启动后立即结束应用程序,这样您就只有一个应用程序在运行。

此方案适用于只需要提升其功能的某些部分的应用程序 - 例如需要访问 Program Files 的自动自我更新安装程序 - 而不是始终需要管理访问权限的应用程序。

【讨论】:

  • 所以我确实添加了 this.Close();应用程序.Exit();在进程 p = Process.Start(startInfo) 之后;但随后它会在 Application.Run(new Form1()); “无法启动已处理的应用程序”??
  • 我会敦促您也检查其他答案,以获得实现您想要的替代方法。
【解决方案3】:

This 是一种更好的方法,因为您的应用程序从一开始就需要管理员权限。

【讨论】:

  • 我尝试过使用它,但现在当我从 VS 运行应用程序时,它要求我“在不同的凭据下重新启动”,如果我这样做,它想对计算机进行更改..??这安全吗?我的意思是我不想只为这个应用程序永久地这样做..
  • 安全是相对的。您显然在做一些天生不安全的事情,因为您需要在应用程序中提升权限。将清单添加到您的应用程序只会影响您正在处理的应用程序,因此不会影响您的其他项目,除非您也将清单包含在这些应用程序中。一直以提升的权限运行 VS 并不是我的做法,我无法真正解决这可能为您打开的漏洞,因为其中一些将取决于插件和其他因素。
  • 您可以使用 Internet Archive Wayback Machine 查看the article 的存档版本。
【解决方案4】:

将 WindowsPrincipal 代码从您的窗体移动到 Program.cs,如下例所示。这将在启动任何表单之前提示用户提供 UAC 权限,并且只有在已授予 UAC 权限时才会启动表单。

        static void Main()
        {
            WindowsPrincipal pricipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
            bool hasAdministrativeRight = pricipal.IsInRole(WindowsBuiltInRole.Administrator);

            if (!hasAdministrativeRight)
            {
                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.UseShellExecute = true;
                startInfo.WorkingDirectory = Environment.CurrentDirectory;
                startInfo.FileName = Application.ExecutablePath;
                startInfo.Verb = "runas";
                try
                {
                    Process p = Process.Start(startInfo);
                    Application.Exit();
                }
                catch (System.ComponentModel.Win32Exception ex)
                {
                    MessageBox.Show("This utility requires elevated priviledges to complete correctly.", "Error: UAC Authorisation Required", MessageBoxButtons.OK);
//                    Debug.Print(ex.Message);
                    return;
                }
            }
            else
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
            }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-17
    • 1970-01-01
    • 1970-01-01
    • 2011-05-21
    • 2013-06-14
    • 1970-01-01
    • 2011-02-20
    • 2019-10-07
    相关资源
    最近更新 更多