2011-08-19 31 views
5

我正在編寫一個C#winform應用程序,該應用程序啓動第二個進程來執行shell命令,如「dir」和「ping」。我重定向第二個進程的輸出,以便我的應用程序可以接收命令結果。它大致工作正常。C#:按行獲取外部shell命令結果

唯一的問題是我的winform應用程序接收命令行輸出作爲一個整體而不是逐行。例如,它必須等待外部「ping」命令完成(需要幾秒鐘或更長時間),然後一次接收整個輸出(多行)。

我想要的是應用程序實時接收cmdline輸出,即通過行而不是塊。這是可行的嗎?

我使用此代碼讀取輸出: 而(!(結果= proc.StandardOutput.ReadLine())= NULL)

但它不工作,我所期望的方式。 在此先感謝。

編輯:這是我使用的代碼:使用while ((result = proc.StandardOutput.ReadLine()) != null)你應該使用的

System.Diagnostics.ProcessStartInfo procStartInfo = new 
      System.Diagnostics.ProcessStartInfo("cmd", "/c " + command); 

    procStartInfo.WindowStyle = ProcessWindowStyle.Hidden; 

    // The following commands are needed to redirect the standard output. 
    procStartInfo.RedirectStandardOutput = true; 
    procStartInfo.UseShellExecute = false; 
    procStartInfo.CreateNoWindow = true; 
    // Now we create a process, assign its ProcessStartInfo and start it 
    System.Diagnostics.Process proc = new System.Diagnostics.Process(); 
    proc.StartInfo = procStartInfo; 
    proc.Start(); 

    // Get the output into a string 
    string result; 
    try { 
     while ((result = proc.StandardOutput.ReadLine()) != null) 
     { 
      AppendRtfText(result+"\n", Brushes.Black); 
     } 
    } // here I expect it to update the text box line by line in real time 
     // but it does not. 
+1

[可能重複(http://stackoverflow.com/questions/ 415620/redirect-console-output-to-textbox-in-separate-program-c) –

+0

顯示你嘗試的代碼將會很有幫助。 –

回答

3

看看this msdn article中關於如何完成讀取異步的示例。

除此之外,我期待你的代碼做現在逐行讀取,但用戶界面不會得到任何時間重繪(缺少Application.DoEvents();更新RTFTextBox

+0

謝謝@Eddy,你是對的。但DoEvents()在WPF中不可用。我用這個解決方案:http://stackoverflow.com/questions/4502037/where-is-the-application-doevents-in-wpf – Charlie

2

相反的循環:

... 
proc.OutputDataReceived += proc_DataReceived; 
proc.Start(); 
proc.BeginOutputReadLine(); 
proc.WaitForExit(); 

這將啓動異步讀取線,他們到達時,你然後在proc_DataReceived處理程序中處理由e.Data讀取的行,因爲您使用的是BeginOutputReadlinee.Data將是一個字符串行。

0

我有同樣的問題,得到了周圍用下面的。我發現,如果我在外部應用程序有一個錯誤,我越來越沒有輸出使用ReadToEnd()方法,因此切換爲使用逐行流式閱讀器。將切換到使用由Saa'd提供的答案,因爲這看起來是正確的方式來處理它。

還發現此解決方案:c# coding convention public/private contexts這提供了在同一時間處理錯誤,並給予一個更全面的解釋,以使用externalApp.OutputDataReceived += (sender, args) => Console.WriteLine(args.Data);

Process externalApp = new Process(); 
     externalApp.StartInfo.FileName = config.ExternalApps + @"\location\DeleteApp.exe"; 
     externalApp.StartInfo.Arguments = Directory.GetCurrentDirectory() + @"\..\..\..\project\argumentsForDeleteApp.xml"; 
     externalApp.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
     externalApp.StartInfo.UseShellExecute = false; 
     externalApp.StartInfo.RedirectStandardOutput = true; 
     Console.Out.WriteLine(DateTime.UtcNow.ToLocalTime().ToString() + 
      ":###### External app: " + externalApp.StartInfo.FileName + " -  START"); 
     externalApp.Start(); 
     using (StreamReader reader = externalApp.StandardOutput) 
     { 
      while (!reader.EndOfStream) 
      { 
       string result = reader.ReadLine(); 
       Console.Out.WriteLine(result); 
      } 
     } 
     externalApp.WaitForExit();