使用ProcessStartInfo重定向标准输出并提示UAC

我正在研究面向.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导致exception,表明:

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

但是,将其设置为false会导致UAC没有提示权限,我得到一个例外说明:

请求的操作需要提升

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

我已经看到了类似的问题 ,但解决方案是使用app.manifest为我的应用程序提供管理权限。 由于要求,这是我无法做到的。

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

但是这篇文章看起来很神奇,虽然我还没有测试过。

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

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

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

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

要做到这一点:

  1. 在项目文件夹中手动编辑’app.manifest’。
  2. 查找有关UAC Manifest Options的评论,您将看到’requestedExecutionLevel’的3个示例。
  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()