2010-09-04 29 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

相关问题