【发布时间】:2016-11-22 09:07:14
【问题描述】:
我有这个小功能,可以让我免于处理可怕的 System.Diagnostics.Process API:
let HiddenExec (command: string, arguments: string) =
let startInfo = new System.Diagnostics.ProcessStartInfo(command)
startInfo.Arguments <- arguments
startInfo.UseShellExecute <- false
startInfo.RedirectStandardError <- true
startInfo.RedirectStandardOutput <- true
use proc = System.Diagnostics.Process.Start(startInfo)
proc.WaitForExit()
(proc.ExitCode,proc.StandardOutput.ReadToEnd(),proc.StandardError.ReadToEnd())
这很好用,因为我得到了一个包含三个元素的元组,其中包含退出代码、标准输出和标准错误结果。
现在,假设我不想“隐藏”执行。也就是说,我想编写一个假设的、更简单的 Exec 函数。那么解决方案就是不重定向stdout/stderr,我们就完成了:
let Exec (command: string, arguments: string) =
let startInfo = new System.Diagnostics.ProcessStartInfo(command)
startInfo.Arguments <- arguments
startInfo.UseShellExecute <- false
let proc = System.Diagnostics.Process.Start(startInfo)
proc.WaitForExit()
proc.ExitCode
但是,如果我可以重构这两个函数以将它们合并为一个函数,并且只需将“隐藏”布尔标志传递给它,那就太好了:
let NewExec (command: string, arguments: string, hidden: bool) =
这样,NewExec(_,_,false) 也将返回 stdout,stderr(不仅是 exitCode,和以前一样)。问题是,如果我不进行重定向舞蹈 (startInfo.RedirectStandardError <- true),那么稍后我将无法通过 proc.StandardOutput.ReadToEnd() 从输出中读取,因为我收到错误 StandardOut has not been redirected or the process hasn't started yet。
另一种总是重定向输出的选项,如果传递的隐藏标志不正确,则调用Console.WriteLine(eachOutput),但这不是很优雅,因为它会一次性写入缓冲区,而不会在标准输出行之间插入标准错误在屏幕上以他们来的正确顺序。对于长时间运行的进程,它会隐藏增量输出,直到进程完成。
那么这里的替代方案是什么?我是否需要使用 Process 类中的该死事件? :(
干杯
【问题讨论】:
-
只返回null,不重定向流?
-
@JohnPalmer:但我希望调用者也能够读取输出,即使它已经打印到屏幕上
-
我看到的一切基本上都是在说你可以做到这一点,但你会有使用事件。
标签: .net f# system.diagnostics processstartinfo redirectstandardoutput