【问题标题】:Elevating process rigth with UAC without ShellExecute在不使用 ShellExecute 的情况下使用 UAC 提升流程可靠性
【发布时间】:2013-10-15 13:39:31
【问题描述】:

我们遇到了一些代码问题,该代码已经用于提升安装新打印机的辅助进程的权限。

我在这里找到了这个答案,它几乎与我们的代码相符: Windows 7 and Vista UAC - Programmatically requesting elevation in C#

唯一的区别是我们将 ShellExecute 设置为 false。这导致了进程需要提升权限的 Win32Exception。使用 ShellExecute 解决了这个问题。

我的问题是:为什么?很可能有一个有意义的答案,并且真的会理解发生了什么,所以下次需要类似的东西时我会知道。

非常感谢所有提示!

【问题讨论】:

  • 基本的“为什么”是“辅助进程”存在重大问题。它应该要求提升本身。

标签: c# uac


【解决方案1】:

以编程方式提升新进程的方法是让 shell 使用动词 runas 执行可执行文件。这是唯一受支持的方法。为了将runas 动词传递给shell,您需要调用合适的Win32 API 函数。可能的候选人包括ShellExecuteShellExecuteEx

UseShellExecute 属性确定在您调用 Process.Start 时使用哪个 API 调用。如果UseShellExecutetrue,则调用ShellExecuteEx。否则会调用 CreateProcess

因此,当您将UseShellExecute 设置为false 时,您切换到使用CreateProcess。而CreateProcess 没有任何机制来提升新进程。所以当UseShellExecutefalse 时,您提供的runas 动词将被简单地忽略,因为CreateProcess 不接收shell 动词。

【讨论】:

    【解决方案2】:

    该行为是因为 Process.Start 在内部使用以下两种 API 之一:CreateProcessShellExecuteEx。只有后者支持 UAC 提升,这就是为什么您必须设置 UseShellExecute = true

    除此之外,还有另一种方法可以实现 UAC 提升,而无需直接启动新进程。您可以编写一个进程外 COM 组件来执行需要运行提升的实际工作。然后,当您实例化组件时,它会在提升的进程中运行(在显示 UAC 提示之后)。当然,不使用 C++/CLI 在 .NET 中编写进程外 COM 组件并不容易。但请参阅this post 了解更多信息。

    【讨论】:

    • 你的第二段是错误的,因为它只适用于特殊的 DLL:“它必须由 Windows 发布者进行数字签名,这是用于签署 Windows 包含的所有代码的证书(它不足以由 Microsoft 签名,因此不包括 Windows 中未提供的 Microsoft 软件)” - 所以这是非常独家的。
    • @coderforlife - 感谢您发现错误!该技术确实有效,但我匆忙链接了一篇完全描述其他内容的文章。我已经把一个链接放到另一个 SO 帖子上。希望这对某人有所帮助。
    • 太棒了!我很高兴它确实有效,现在将考虑使用它(我最初阅读这篇文章是因为我确实希望它有效)。谢谢!
    【解决方案3】:

    Microsoft Channel 9 video that explains the guts of UAC.

    在架构上,只有 ShellExecute 知道如何启动 Consent.exe(UAC 对话框)。所以这就是你必须使用它的原因。

    【讨论】:

      猜你喜欢
      • 2018-12-05
      • 1970-01-01
      • 1970-01-01
      • 2010-11-05
      • 1970-01-01
      • 2010-10-25
      • 2013-07-16
      • 2014-08-20
      • 1970-01-01
      相关资源
      最近更新 更多