【问题标题】:C# get process output while runningC#在运行时获取进程输出
【发布时间】:2024-04-14 23:05:01
【问题描述】:

是否有重定向生成进程的标准输出并在其发生时捕获它。我所看到的一切都只是在该过程完成后执行 ReadToEnd 。我希望能够在打印时获得输出。

编辑:

    private void ConvertToMPEG()
    {
        // Start the child process.
        Process p = new Process();
        // Redirect the output stream of the child process.
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.RedirectStandardOutput = true;
        //Setup filename and arguments
        p.StartInfo.Arguments = String.Format("-y -i \"{0}\" -target ntsc-dvd -sameq -s 720x480 \"{1}\"", tempDir + "out.avi", tempDir + "out.mpg");
        p.StartInfo.FileName = "ffmpeg.exe";
        //Handle data received
        p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
        p.Start();
    }

    void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        Debug.WriteLine(e.Data);
    }

【问题讨论】:

    标签: c# process redirectstandardoutput


    【解决方案1】:

    使用流程中的Process.OutputDataReceived 事件,接收您需要的数据。

    例子:

    var myProc= new Process();
    
    ...            
    myProc.StartInfo.RedirectStandardOutput = true;
    myProc.OutputDataReceived += new DataReceivedEventHandler(MyProcOutputHandler);
    
    ...
    
    private static void MyProcOutputHandler(object sendingProcess, 
                DataReceivedEventArgs outLine)
    {
                // Collect the sort command output. 
        if (!String.IsNullOrEmpty(outLine.Data))
        {
          ....    
        }
    }
    

    【讨论】:

    • 是的,此外,您需要将 RedirectStandardOutput 设置为 true 才能正常工作。
    • 我试过了,但我没有运气。它运行良好,但从未命中回调。也许这是打印输出方式的问题。我将它与 ffmpeg 一起使用。我会将我的代码添加到原始帖子中。
    • 在我开始这个过程之后,我还必须添加myProc.BeginOutputReadLine();
    • @lii dataReceivedEventHandler 文档说:“当重定向流关闭时,将向事件处理程序发送一个空行。确保您的事件处理程序在访问 Data 属性之前检查此情况。例如,您可以使用静态方法 String.IsNullOrEmpty 来验证事件处理程序中的 Data 属性。"
    • @RToyo IsNullOrEmpty 不应使用,因为 null 表示不继续,但处理应在空行后继续。
    【解决方案2】:

    所以经过一番挖掘后,我发现 ffmpeg 使用 stderr 进行输出。这是我修改后的代码以获取输出。

            Process p = new Process();
    
            p.StartInfo.UseShellExecute = false;
    
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
    
            p.StartInfo.Arguments = String.Format("-y -i \"{0}\" -target ntsc-dvd -sameq -s 720x480 \"{1}\"", tempDir + "out.avi", tempDir + "out.mpg");
            p.StartInfo.FileName = "ffmpeg.exe";
    
            p.ErrorDataReceived += new DataReceivedEventHandler(p_ErrorDataReceived);
            p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
    
            p.Start();
    
            p.BeginErrorReadLine();
            p.WaitForExit();
    

    【讨论】:

    • 很好的例子!不幸的是,不适用于 p.StartInfo.UseShellExecute = true; (例如,当尝试捕获长时间运行的 msbuild 进程并在 Visual Studio 输出窗口中实时显示输出时)。
    最近更新 更多