visual-studio 将子进程的输出(stdout、stderr)重定向到 Visual Studio 中的输出窗口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3642147/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 12:26:15  来源:igfitidea点击:

Redirect the output (stdout, stderr) of a child process to the Output window in Visual Studio

c#visual-studiovisual-studio-2008stdoutoutput-window

提问by Andrew Russell

At the moment I am starting a batch file from my C# program with:

目前我正在从我的 C# 程序启动一个批处理文件:

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

What I would like to be able to do is redirect the output (stdout and stderr) of that child process to the Output window in Visual Studio (specifically Visual C# Express 2008).

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

Is there a way to do that?

有没有办法做到这一点?

(Additionally: such that it's not all buffered up and then spat out to the Output window when the child process finishes.)

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



(BTW: At the moment I can get stdout (but not stderr) of the parentprocess to appear in the Output window, by making my program a "Windows Application" instead of a "Console Application". This breaks if the program is run outside Visual Studio, but this is ok in my particular case.)

(顺便说一句:目前,通过使我的程序成为“Windows 应用程序”而不是“控制台应用程序”,我可以让进程的标准输出(但不是标准错误)出现在输出窗口中。如果程序运行,这会中断在 Visual Studio 之外,但这在我的特殊情况下是可以的。)

回答by Mark H

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

Same idea for Error, just replace Outputin those method/property names.

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

回答by UweBaemayr

A variation of this works for me --posting this now because I wish I'd found it earlier. Note that this is just a fragment extracted from the real code so there may be trivial errors.

这个变体对我有用——现在发布这个是因为我希望我早点找到它。请注意,这只是从真实代码中提取的片段,因此可能存在细微错误。

The technique is based on some MSDN code. What I haven't been able to figure out is how to get the output window to update "on the fly". It doesn't update until after this task returns.

该技术基于一些 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();
}

回答by Roger Lipscombe

What's going on here is that Visual Studio is displaying the debug output from the program in the Output Window. That is: if you use Trace.WriteLine, it'll appear in the Output Window, because of the default trace listener.

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

Somehow, your Windows Form application (when it uses Console.WriteLine; I'm assuming you're using Console.WriteLine) is also writing debug output, and Visual Studio is picking this up.

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

It won't do the same for child processes, unless you explicitly capture the output and redirect it along with your output.

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

回答by GenEric35

Have you considered using a DefaultTraceListener?

您是否考虑过使用DefaultTraceListener

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