我正在开发一个应用程序,它调用多个命令行应用程序对某些视频文件进行一些后期处理。
目前我正在尝试使用Comskip来识别我的有线电视卡调谐器中的视频录制中的商业广告时段。运行得很好,但是我在获取所需的屏幕输出时遇到了问题。
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”“--ini = 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();
但如果我使用这些选项运行,则该过程似乎会挂起。
我是否遗漏了一些内容以捕捉我希望的内容,或者此应用程序的输出流是否可能会转移到无法访问的其他位置?
答案 0 :(得分:2)
请参阅RedirectStandardOutput
上的docs。在读取输出之前等待子进程结束可能会导致挂起。
特别是,这个例子说不要做你做过的事情:
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
并更新处理程序中的进度条。
答案 1 :(得分:2)
您必须设置以下内容:
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;
}
}