5

我正在开发一个面向 .NET 3.0 的 WPF 应用程序。我需要调用一个需要管理权限的 exe。我可以让 UAC 使用类似的东西来提示许可:

ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.Verb = "runas";
startInfo.UseShellExecute = true;
startInfo.FileName = "target.exe";

Process p = new Process();
p.StartInfo = startInfo;
p.Start();

我的问题是我需要重定向标准输出,这样做会UseShellExecute = true导致异常说明:

Process 对象必须将 UseShellExecute 属性设置为 false 才能重定向 IO 流

但是,将其设置为 false 会导致 UAC 不提示许可,并且出现异常说明:

请求的操作需要提升

如何重定向标准输出并提示 UAC?

我见过这个类似的问题,但是解决方案是使用 app.manifest 来授予我的应用程序管理权限。由于要求,这是我无法做到的。

4

2 回答 2

3

UseShellExecute必须设置为false重定向 IO,并true使用该Verb属性。所以你不能。

但是这篇文章似乎很神奇,虽然我没有测试过。

它是用 C++ 编写的,但是可以很容易地创建一个包装 API,以便使用DllImport.


注意:如果您想在两个程序之间传递数据并访问目标程序的源代码,您可以轻松地重新设计您的应用程序以使用Named Pipes而不是重定向标准 I/O。

于 2013-10-15T12:39:37.170 回答
3

还有另一个非常简单的解决方案:

如果您想运行提升的子可执行文件并重定向输出(可选地包括窗口隐藏),那么您的主代码也必须运行提升。这是一个安全要求

要做到这一点:

  1. 手动编辑您app.manifest的项目文件夹。
  2. 查找有关 UAC Manifest Options 的评论,您将看到 3 个示例requestedExecutionLevel
  3. 在评论下,找到asInvoker当前启用的棘手,并将其替换为requireAdministrator.
  4. 重新启动 Visual Studio 以使其生效,并且在重新构建您的应用程序后,它应该具有典型的 UAC 盾牌图标。

现在您的代码将运行提升,它启动的所有内容也将提升,您还可以捕获输出流。这是 VB.NET 中的一个示例:

Dim startInfo As New ProcessStartInfo
startInfo.Verb = "runas"
startInfo.FileName = "subprocess-elevated.exe"
startInfo.Arguments = "arg1 arg2 arg3"
startInfo.WorkingDirectory = Environment.CurrentDirectory
startInfo.WindowStyle = ProcessWindowStyle.Hidden
startInfo.CreateNoWindow = True
Dim p As Process = New Process()
p.StartInfo = startInfo
p.StartInfo.UseShellExecute = False
p.StartInfo.RedirectStandardOutput = True
p.StartInfo.RedirectStandardError = True
p.Start()
Console.WriteLine(p.StandardOutput.ReadToEnd)
Console.WriteLine(p.StandardError.ReadToEnd)
p.WaitForExit()
于 2017-02-23T18:17:31.810 回答