以下是代码:
var output = new StringWriter();
var error = new StringWriter();
var p = new Process();
p.StartInfo = new ProcessStartInfo
{
WorkingDirectory = workingDir,
FileName = file,
Arguments = args,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
};
p.OutputDataReceived += (o, e) => { output.WriteLine(e.Data); };
p.ErrorDataReceived += (o, e) => { error.WriteLine(e.Data); };
p.Start();
if (!p.WaitForExit((int)timeout.TotalMilliseconds))
{
p.Kill();
throw new Exception("Timeout expired.");
}
string errorData = error.ToString();
if (errorData.Length > 0)
throw new Exception(errorData);
return output.ToString();
我希望只要数据可用就会调用OutputDataReceived
和ErrorDataReceived
个处理程序,但这种情况不会发生。对于将大量内容输出到stdout的进程,此代码最终会在throw new Exception("Timeout expired.");
上退出。我尝试将一些调试代码抛入处理程序,但它永远不会被调用。指定out / err处理程序的全部意义是不是异步调用它们?
答案 0 :(得分:4)
来自the docs:
在StandardOutput上的异步读取操作期间启用该事件。要启动异步读取操作,必须重定向Process的StandardOutput流,将事件处理程序添加到OutputDataReceived事件,并调用BeginOutputReadLine 。此后,每次进程将一行写入重定向的StandardOutput流时,OutputDataReceived事件都会发出信号,直到进程退出或调用CancelOutputRead。
您没有执行任何异步读取,因此不会触发该事件。
如果你只是在启动过程后添加对p.BeginOutputReadline()
的调用,它就会起作用。同样,要读取错误流,请调用BeginErrorReadLine()
。
答案 1 :(得分:1)
要开始接收标准输出和标准错误的事件,您需要分别拨打BeginOutputReadLine()
和BeginErrorReadLine()
。