2010-11-06 68 views
16

我将执行一个Process(lame.exe)来将WAV文件编码为MP3。如何在流程操作期间逐行捕获流程STDOUT和STDERR。 (C#)

我想处理进程的STDOUT和STDERR以显示进度信息。

我需要使用线程吗?我无法理解它。

一些简单的示例代码将不胜感激。

感谢

+0

我发现样本[这里](http://msdn.microsoft.com/en-us/library/system。 diagnostics.process%28v = vs80%29.aspx),它显示了如何使用有帮助的线程读取stdout和stderr。另请参阅http://cleancode.sourceforge.net/api/csharp/html/T_CleanCode_IO_ExecProcess.htm。 – 2012-03-08 18:44:55

回答

7

如果通过Process类运行,您可以重定向数据流,因此您可以处理它们。您可以同步或异步地从stdout或stderr读取。要启用重定向,请为要重定向的流设置适当的重定向属性为true(例如,RedirectStandardOutput),并将UseShellExecute设置为false。然后,您可以启动该流程并从流中读取数据。您也可以提供输入重定向标准输入。

例如,处理和打印任何进程写入stdout同步

var proc = new Process() 
{ 
    StartInfo = new ProcessStartInfo(@"SomeProcess.exe") 
    { 
     RedirectStandardOutput = true, 
     UseShellExecute = false, 
    } 
}; 
if (!proc.Start()) 
{ 
    // handle error 
} 
var stdout = proc.StandardOutput; 
string line; 
while ((line = stdout.ReadLine()) != null) 
{ 
    // process and print 
    Process(line); 
    Console.WriteLine(line); 
} 
+11

这不捕获STDERR。 – 2010-11-06 06:27:46

+0

@Albin:很明显,我没有写这个例子。 – 2010-11-06 06:41:19

1

an MSDN example这...这是一个简化版本:

var StdOut = ""; 
var StdErr = ""; 

var stdout = new StringBuilder(); 
var stderr = new StringBuilder(); 

var psi = new ProcessStartInfo(); 
psi.FileName = @"something.exe"; 
psi.CreateNoWindow = true; 
psi.UseShellExecute = false; 
psi.RedirectStandardOutput = true; 
psi.RedirectStandardError = true; 

var proc = new Process(); 
proc.StartInfo = psi; 
proc.OutputDataReceived += (sender, e) => { stdout.AppendLine(e.Data); }; 
proc.ErrorDataReceived += (sender, e) => { stderr.AppendLine(e.Data); }; 
proc.Start(); 
proc.BeginOutputReadLine(); 
proc.BeginErrorReadLine(); 
proc.WaitForExit(10000); // per sachin-joseph's comment 

StdOut = stdout.ToString(); 
StdErr = stderr.ToString(); 
+0

总是通过超时调用'waitForExit'来防止无限等待的机会。 'waitForExit(10000)'=>等待10秒钟。 – 2017-09-04 08:46:39