1

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

现在,我正在尝试使用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 调整文件\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();,但如果我使用这些选项运行,该过程似乎会挂起。

我是否遗漏了一些东西来捕捉我想要的东西,或者这个应用程序的输出流是否有可能转到其他无法访问的地方?

4

2 回答 2

2

请参阅 上的文档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更新处理程序中的进度条。

于 2012-12-30T21:25:04.510 回答
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;
     }
  }
于 2012-12-30T21:27:00.560 回答