2010-09-04 93 views
11

目前,我從我的C#程序啓動一個批處理文件:重定向子進程的輸出(stdout,標準錯誤)到輸出窗口在Visual Studio

System.Diagnostics.Process.Start(@"DoSomeStuff.bat"); 

我想是能夠做到的是將該子進程的輸出(stdout和stderr)重定向到Visual Studio中的輸出窗口(特別是Visual C#Express 2008)。

有沒有辦法做到這一點?

(另外:這樣,它不是所有的緩存起來,然後吐出來當子進程結束Output窗口)


(BTW:現在我可以得到標準輸出(而不是標準錯誤)的父級進程出現在輸出窗口中,通過使我的程序成爲「Windows應用程序」而不是「控制檯應用程序」。如果程序在Visual Studio外運行,這會中斷,但在我的特殊情況下)

+0

所有的作品都在這裏。重定向進程的輸出,使用Trace將其放到Output窗口中。 – 2010-09-04 14:27:33

+0

你有沒有想過如何重定向子進程的輸出?下面給出的答案可以重定向父進程的輸出,但不是子進程的輸出。 – Fiona 2017-01-31 23:56:23

回答

20
process.StartInfo.CreateNoWindow = true; 
process.StartInfo.UseShellExecute = false; 
process.StartInfo.RedirectStandardOutput = true; 
process.OutputDataReceived += (sender, args) => Console.WriteLine(args.Data); 
process.Start(); 
process.BeginOutputReadLine(); 

process.WaitForExit(); 

同樣的想法,只是在那些方法/屬性名稱替換Output

+6

這個答案大多是正確的。它缺少一些東西。特別是:之後在'Begin ... ReadLine'和'WaitForExit'之前'開始'調用。同樣,將'RedirectStandardInput'設置爲true可以修復由批處理文件中的某個程序(特別是plink)導致的問題,即使該批處理文件沒有使用該標準,也需要一個有效的標準輸入。 – 2010-09-04 14:29:41

+0

'WaitForExit()'會導致無限的等待。始終使用超時調用方法:'process.WaitForExit(10000)'=>等待10秒。 – 2017-09-04 08:44:51

-3

您是否考慮使用DefaultTraceListener

//Create and add a new default trace listener. 
    DefaultTraceListener defaultListener; 
    defaultListener = new DefaultTraceListener(); 
    Trace.Listeners.Add(defaultListener); 
+2

這甚至不能*遠程*回答我的問題。從鏈接的MSDN頁面:「這個類的一個實例會自動添加到Debug.Listeners和Trace.Listeners集合中,顯式添加第二個DefaultTraceListener將導致調試器輸出窗口中出現重複消息,併爲斷言重複消息框。」你的回答比完全無用。 – 2010-09-04 12:53:44

+4

復仇downvote,呃?保持優雅,GenEric35。 – 2010-09-04 13:03:14

+0

+1對Anderw的MSDN頁面解釋 – prabhakaran 2014-04-22 10:54:36

2

這裏發生的事情是Visual Studio在輸出窗口中顯示程序的調試輸出。也就是說:如果使用Trace.WriteLine,由於默認的跟蹤偵聽器,它將出現在輸出窗口中。不知怎的,你的Windows Form應用程序(當它使用Console.WriteLine;我假設你使用的是Console.WriteLine)也在編寫調試輸出,而Visual Studio正在挑選它。

它不會爲子進程執行相同的操作,除非您明確捕獲輸出並將其與輸出一起重定向。對於Error

+0

這基本上是我想問的 - 你怎麼做最後一點? (而且,我意識到我從我的問題中忽略了這一點:如何做到「恰如其分」?) – 2010-09-04 13:40:21

8

這個變化對我有用 - 現在發佈這個,因爲我希望能早些發現它。 請注意,這只是從實際代碼中提取的一個片段,因此可能存在微不足道的錯誤。

該技術基於一些MSDN代碼。我一直無法弄清楚的是如何讓輸出窗口「即時」更新。它不會更新,直到此任務返回。

// Set this to your output window Pane 
private EnvDTE.OutputWindowPane _OutputPane = null; 

// Methods to receive standard output and standard error 

private static void StandardOutputReceiver(object sendingProcess, DataReceivedEventArgs outLine) 
{ 
    // Receives the child process' standard output 
    if (! string.IsNullOrEmpty(outLine.Data)) { 
     if (_OutputPane != null) 
      _OutputPane.Write(outLine.Data + Environment.NewLine); 
    } 
} 

private static void StandardErrorReceiver(object sendingProcess, DataReceivedEventArgs errLine) 
{ 
    // Receives the child process' standard error 
    if (! string.IsNullOrEmpty(errLine.Data)) { 
     if (_OutputPane != null) 
      _OutputPane.Write("Error> " + errLine.Data + Environment.NewLine); 
    } 
} 

// main code fragment 
{ 
    // Start the new process 
    ProcessStartInfo startInfo = new ProcessStartInfo(PROGRAM.EXE); 
    startInfo.Arguments = COMMANDLINE; 
    startInfo.WorkingDirectory = srcDir; 
    startInfo.UseShellExecute = false; 
    startInfo.RedirectStandardOutput = true; 
    startInfo.RedirectStandardError = true; 
    startInfo.CreateNoWindow = true; 
    Process p = Process.Start(startInfo); 
    p.OutputDataReceived += new DataReceivedEventHandler(StandardOutputReceiver); 
    p.BeginOutputReadLine(); 
    p.ErrorDataReceived += new DataReceivedEventHandler(StandardErrorReceiver); 
    p.BeginErrorReadLine(); 
    bool completed = p.WaitForExit(20000); 
    if (!completed) 
    { 
     // do something here if it didn't finish in 20 seconds 
    } 
    p.Close(); 
} 
+0

這不會得到stdout和stderror在正確的順序.. – paulm 2013-08-30 09:20:23

+0

@ paulm你是什麼意思,它不會得到正確的順序?這段代碼在重定向stderr時不起作用(標準輸出正在工作)。任何想法爲什麼? – rboy 2015-01-15 00:16:42

+0

使用我的問題的答案 - 這不會得到正確的順序stderr和標準輸出,即如果應用程序不出,錯,出,錯,你可能會出,出,錯,錯誤等 – paulm 2015-01-17 12:10:20

相關問題