如何获得System.Diagnostics.Process的输出?

我这样运行ffmpeg:

System.Diagnostics.Process p = new System.Diagnostics.Process(); p.StartInfo = new System.Diagnostics.ProcessStartInfo(ffmpegPath, myParams); p.Start(); p.WaitForExit(); 

…但问题是,与ffmpeg控制台popup并立即消失,所以我不能得到任何反馈。 我甚至不知道过程是否正确运行。

那么我怎么能:

  • 告诉控制台保持打开

  • 在C#中检索控制台显示的内容

你需要做的是捕获标准输出流:

 p.StartInfo.RedirectStandardOutput = true; p.StartInfo.UseShellExecute = false; // instead of p.WaitForExit(), do string q = ""; while ( ! p.HasExited ) { q += p.StandardOutput.ReadToEnd(); } 

你也可能需要做类似于StandardError事情。 然后你可以用q来做你想做的事情。

正如我在其中一个问题中发现的那样,这有点挑剔

Jon Skeet指出,像这样使用字符串连接并不聪明, 你应该使用一个StringBuilder

 p.StartInfo.RedirectStandardOutput = true; p.StartInfo.UseShellExecute = false; // instead of p.WaitForExit(), do StringBuilder q = new StringBuilder(); while ( ! p.HasExited ) { q.Append(p.StandardOutput.ReadToEnd()); } string r = q.ToString(); 

卢卡斯的答案有一个竞争条件:如果进程快速结束while循环(或从未输入),即使有一些输出,这就是你可能会错过一些数据。 为了防止这种情况,应该在退出进程执行另一个ReadToEnd

(请注意,与旧版本的答案相比,一旦process.HasExited标志为true,我不再需要WaitForExit ,所以这归结为:)

 using (var process = Process.Start(startInfo)) { var standardOutput = new StringBuilder(); // read chunk-wise while process is running. while (!process.HasExited) { standardOutput.Append(process.StandardOutput.ReadToEnd()); } // make sure not to miss out on any remaindings. standardOutput.Append(process.StandardOutput.ReadToEnd()); // ... } 

有关与ffmpeg直接相关的更具体的答案,将“-report”命令传递给ffmpeg将使其将日志转储到当前目录中,同时显示进程中所说的内容。

'-报告'

将完整的命令行和控制台输出转储到当前目录中名为program-YYYYMMDD-HHMMSS.log的文件中。 这个文件可以用于错误报告。 这也意味着-loglevel冗长。

注意:将环境变量FFREPORT设置为任何值都具有相同的效果。

从FFMpeg文档 。

我知道这个问题是旧的,但我会加入它。

如果你只想显示一个命令行进程的输出,并且你从一个控制台窗口产生这个进程,你只需要重定向标准输入(是的,我知道它听起来是错误的,但它的工作原理)。

所以:

 System.Diagnostics.Process p = new System.Diagnostics.Process(); p.StartInfo = new System.Diagnostics.ProcessStartInfo(ffmpegPath, myParams); p.UseShellExecute = false; p.RedirectStandardInput = true; p.Start(); p.WaitForExit(); 

会做得很好。