2012-07-24 19 views
32

我试图在“实时”捕获进程输出(它正在运行时)。我使用的代码相当简单(见下文)。出于某种奇怪的原因,OutputDataReceived事件从不会被调用。为什么?通过OutputDataReceived事件捕获进程输出

private void button2_Click(object sender, EventArgs e) 
    { 
     // Setup the process start info 
     var processStartInfo = new ProcessStartInfo("ping.exe", "-t -n 3 192.168.100.1") 
     { 
     UseShellExecute = false, 
     RedirectStandardOutput = true 
     }; 

     // Setup the process 
     mProcess = new Process { StartInfo = processStartInfo, EnableRaisingEvents = true }; 

     // Register event 
     mProcess.OutputDataReceived += OnOutputDataReceived; 

     // Start process 
     mProcess.Start(); 
     mProcess.WaitForExit(); 
    } 

    void OnOutputDataReceived(object sender, DataReceivedEventArgs e) 
    { 
     //Never gets called... 
    } 

回答

52

你需要调用

mProcess.BeginOutputReadLine(); 

BeginOutputReadLine - “对应用程序的重定向StandardOutput流开始异步读取操作。”

+6

此外,外部PROCES要求在其输出的东西的时刻刷新其输出缓冲区。如果没有刷新,输出缓冲区会持续到外部进程退出;这使得主应用程序无法捕捉输出“实时”。 – 2013-05-07 16:52:22

+1

@BobKruithof:够了。外部流程确实需要实际发送数据,但没有任何其他信息是最容易解决的问题。 :) – Chris 2013-05-08 15:40:55

+1

另外,有些应用程序正在写入标准的ERROR而不是标准的OUTPUT。通常,手动查看输出时不会有所作为。因此,尝试添加以防万一:分别为“RedirectStandardError = true”和“mProcess.BeginErrorReadLine();”。 – altumano 2014-03-24 18:37:13

0

void ExecuteCommand(string cmdpath, string cmdargs) 
{ 
    string command = cmdpath + " " + cmdargs; 

    tabc_results.SelectTab(1); 
    DoConsole("\r\nCmd>> " + command + "\r\n"); 

    var processInfo = new System.Diagnostics.ProcessStartInfo("cmd.exe", "/c " + command); 
    processInfo.CreateNoWindow = true; 
    processInfo.UseShellExecute = false; 
    processInfo.RedirectStandardError = true; 
    processInfo.RedirectStandardOutput = true; 

    var process = System.Diagnostics.Process.Start(processInfo); 

    process.OutputDataReceived += (
     object sender, System.Diagnostics.DataReceivedEventArgs e 
    ) => DoConsole("stdout>> " + e.Data + "\r\n"); 
    //Console.WriteLine("output>>" + e.Data); 
    process.BeginOutputReadLine(); 

    process.ErrorDataReceived += (
     object sender, System.Diagnostics.DataReceivedEventArgs e 
    ) =>DoConsole("stderr>> " + e.Data + "\r\n"); 
    //Console.WriteLine("error>>" + e.Data); 
    process.BeginErrorReadLine(); 

    process.WaitForExit(); 

    DoConsole("retcode>> " + process.ExitCode.ToString() + "\r\n"); 
    //Console.WriteLine("ExitCode: {0}", process.ExitCode); 
    process.Close(); 
}