将子进程的输出(stdout,stderr)重定向到Visual Studio中的“输出”窗口

时间:2010-09-04 12:00:33

标签: c# visual-studio visual-studio-2008 stdout output-window

目前,我正在使用以下命令从我的C#程序启动批处理文件:

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

我希望能够将该子进程的输出(stdout和stderr)重定向到Visual Studio中的Output窗口(特别是Visual C#Express 2008)。

有办法吗?

(另外:这样就不会全部缓冲,然后在子进程完成时吐出到Output窗口。)


(顺便说一句:目前我可以通过使我的程序成为“Windows应用程序”而不是“控制台”,将进程的stdout(但不是stderr)显示在“输出”窗口中应用程序“。如果程序在Visual Studio外部运行,则会中断,但在我的特定情况下这是正常的。)

4 个答案:

答案 0 :(得分:22)

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();

Error的相同想法,只需在这些方法/属性名称中替换Output

答案 1 :(得分: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();
}

答案 2 :(得分:2)

这里发生的是Visual Studio在输出窗口中显示程序的调试输出。也就是说:如果使用Trace.WriteLine,它将出现在输出窗口中,因为默认的跟踪侦听器。

不知何故,你的Windows窗体应用程序(当它使用Console.WriteLine;我假设你正在使用Console.WriteLine时)也在编写调试输出,而Visual Studio正在选择它。

对于子进程,它不会执行相同的操作,除非您明确捕获输出并将其与输出一起重定向。

答案 3 :(得分:-4)

您是否考虑过使用DefaultTraceListener

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