从Process.Start()获得所需输出的问题

时间:2012-12-30 21:19:55

标签: c# command-line

我正在开发一个应用程序,它调用多个命令行应用程序对某些视频文件进行一些后期处理。

目前我正在尝试使用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抓住屏幕上显示的内容,就像手动启动应用程序时一样(下面的屏幕截图),这是应用程序正在进行的操作的连续反馈,并混合在输出是提供%进度的行,我想用它来更新进度条

output from commandline

但运行上面的代码只能给我:

  

使用的命令行是:   “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();但如果我使用这些选项运行,则该过程似乎会挂起。

我是否遗漏了一些内容以捕捉我希望的内容,或者此应用程序的输出流是否可能会转移到无法访问的其他位置?

2 个答案:

答案 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();

并捕获ReadOutputErrorOutput

中的输出
  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;
     }
  }