2012-07-24 38 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(); 
}