从Process.Start()获得所需输出的问题
我正在研究一个应用程序,它调用几个命令行应用程序来对某些video文件进行一些后期处理。
现在我正在尝试使用Comskip从我的有线卡调谐器中识别video录制中的商业广告。 这运行得很好,但我在获取所需的屏幕输出时遇到问题。
String stdout = null; using (var process = new Process()) { var start = new ProcessStartInfo(comskip, cmdLine); start.WindowStyle = ProcessWindowStyle.Normal; start.CreateNoWindow = true; start.UseShellExecute = false; start.RedirectStandardOutput = true; process.StartInfo = start; process.Start(); process.WaitForExit(); stdout = process.StandardOutput.ReadToEnd(); }
我期待stdout
能够抓住屏幕上显示的内容,就像手动启动应用程序时一样(下面的屏幕截图),这是应用程序正在执行的操作的连续馈送,并且在输出中混合使用的是给出%的行进度,我想用它来更新进度条
但运行上面的代码只能给我:
使用的命令行是:“C:\ Users \ Chris \ Google Drive \ Tools \ ComSkip \ comskip.exe”“C:\ Users \ Chris \ Desktop \ ComSkip Tuning Files \ Modern Family.wtv”“ – ni = C: \ Users \ Chris \ Desktop \ ComSkip Tuning Files \ comskip_ModernFamily.ini“
根据命令行将ini文件设置为C:\ Users \ Chris \ Desktop \ ComSkip Tuning Files \ comskip_ModernFamily.ini使用C:\ Users \ Chris \ Desktop \ ComSkip Tuning Files \ comskip_ModernFamily.ini获取初始值。
我还尝试重定向StandardError
流并抓取process.StandardError.ReadToEnd();
但如果我使用这些选项运行,该过程似乎会挂起。
我错过了一些东西来捕捉我希望的东西,或者这个应用程序的输出流是否可能在其他无法访问的地方?
您必须设置以下内容:
process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; process.StartInfo.UseShellExecute = false; process.OutputDataReceived += new DataReceivedEventHandler(ReadOutput); process.ErrorDataReceived += new DataReceivedEventHandler(ErrorOutput); process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); process.WaitForExit();
并在ReadOutput
和ErrorOutput
捕获输出
private static void ErrorOutput(object sender, DataReceivedEventArgs e) { if (e.Data != null) { stdout = "Error: " + e.Data; } } private static void ReadOutput(object sender, DataReceivedEventArgs e) { if (e.Data != null) { stdout = e.Data; } }
请参阅RedirectStandardOutput
上的文档 。 在读取输出之前等待子进程结束可能会导致挂起。
特别是,这个例子说不要做你做过的事情:
Process p = new Process(); // Redirect the output stream of the child process. p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.FileName = "Write500Lines.exe"; p.Start(); // Do not wait for the child process to exit before // reading to the end of its redirected stream. // p.WaitForExit(); // Read the output stream first and then wait. string output = p.StandardOutput.ReadToEnd(); p.WaitForExit();
您应该使用事件OutputDataReceived
并可能使用ErrorDataReceived
并更新处理程序中的进度条。