2010-01-06 150 views
11

我正在啓動一個控制檯應用程序,但是當我重定向標準輸出時,我總是一無所得!process.standardoutput.ReadToEnd()總是空的?

當我不重定向它,並設置CreateNoWindowfalse,我在控制檯中正確地看到的一切,但是當我把它重定向,StandardOutput.ReadToEnd()總是返回一個空字符串。

 Process cproc = new Process(); 
     cproc.StartInfo.CreateNoWindow = true; 
     cproc.StartInfo.FileName = Dest; 
     cproc.StartInfo.RedirectStandardOutput = true; 
     cproc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
     cproc.StartInfo.UseShellExecute = false; 
     cproc.EnableRaisingEvents = true; 
     cproc.Start(); 
     cproc.Exited += new EventHandler(cproc_Exited); 
     while(!stop) 
     { 
      result += cproc.StandardOutput.ReadToEnd(); 
     } 

EventHandler cproc_exited只是設置stoptrue。有人可以解釋爲什麼result總是string.Empty

回答

7

爲什麼你循環?一旦它被讀到最後,它將無法讀取更多的數據,是嗎?

您確定該文本實際上是寫入StandardOutput而不是StandardError

(是的,很顯然你要設置RedirectStandardOutput爲真而不是假的我以爲那只是你複製你的代碼的錯誤版本的情況下。)

編輯:正如我所建議評論,你應該從單獨的線程中讀取標準輸出和標準錯誤。做而不是等到進程退出 - 這可能會導致死鎖,在此等待進程退出,但進程阻止嘗試寫入標準錯誤/標準輸出,因爲您尚未讀取緩衝。

或者,您可以訂閱OutputDataReceived和ErrorDataReceived事件,以避免使用額外的線程。

+0

。 我得到了一個死鎖 – alex 2010-01-06 11:33:15

+0

heey,它的工作原理!看起來像我的朋友(誰做了控制檯程序)搞砸了!它將所有內容寫入錯誤流!我得和他談談,也許他可以解決這個問題。感謝您的快速回答!你從我的電腦前幾小時和幾個小時的時間裏救了我,試圖尋找一個愚蠢的錯誤:) – alex 2010-01-06 11:44:45

+1

@alex:取出while循環 - 它不應該在那裏。理想情況下,使用不同的線程 - 一個從'StandardOutput'讀取,一個從'StandardError'讀取。 – 2010-01-06 11:59:51

6

您已將標準禁止重定向。嘗試改變

cproc.StartInfo.RedirectStandardOutput = false; 

cproc.StartInfo.RedirectStandardOutput = true; 

是否從你MSDN以下工作的樣本?

// Start the child process. 
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(); 
+0

仍然改變不了什麼 – alex 2010-01-06 11:28:26

+0

以及這使得窗口出現,但多數民衆贊成空的,我的結果字符串是空的,太。 這真的令人困惑 – alex 2010-01-06 11:39:07

+0

你檢查了標準錯誤:'output = p.StandardError.ReadToEnd();'? (!stop) { } s + = convproc.StandardOutput.ReadToEnd();如果我將其更改爲 ,則爲 – 2010-01-06 11:41:20

-1

擺脫環路並將電話轉到ReadToEndcproc_Exited。此

+0

壞主意:如果它試圖寫入大量數據的其中沒有什麼是閱讀過程中會掛起。 – 2010-01-06 12:32:38

15

最好的辦法是把輸出重定向並等待事件:

// some of the flags are not needed 
    process.StartInfo.CreateNoWindow = true; 
    process.StartInfo.ErrorDialog = false; 
    process.StartInfo.UseShellExecute = false; 
    process.StartInfo.RedirectStandardError = true; 
    process.StartInfo.RedirectStandardInput = true; 
    process.StartInfo.RedirectStandardOutput = true; 
    process.EnableRaisingEvents = true; 
    process.OutputDataReceived += process_OutputDataReceived; 
    process.ErrorDataReceived += process_OutputDataReceived; 
    process.Exited += process_Exited; 
    process.Start(); 
    process.BeginErrorReadLine(); 
    process.BeginOutputReadLine(); 

    void process_Exited(object sender, System.EventArgs e) 
    { 
     // do something when process terminates; 
    } 

    void process_OutputDataReceived(object sender, DataReceivedEventArgs e) 
    { 
     // a line is writen to the out stream. you can use it like: 
     string s = e.Data; 
    } 

    void process_ErrorDataReceived(object sender, DataReceivedEventArgs e) 
    { 
     // a line is writen to the out stream. you can use it like: 
     string s = e.Data; 
    } 
+0

有用。謝謝。 – 2011-04-28 11:30:01