[英]Redirect the output (stdout, stderr) of a child process to the Output window in Visual Studio
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中的Output窗口(特别是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.) (另外:这样就不会全部缓冲,然后在子进程完成时吐出到Output窗口。)
(BTW: At the moment I can get stdout (but not stderr) of the parent process 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应用程序”而不是“控制台应用程序”来使父进程的stdout(但不是stderr)出现在“输出”窗口中。如果程序运行,这会中断在Visual Studio之外,但在我的特定情况下这是好的。)
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 Output
in those method/property names. 同样的想法是
Error
,只需在这些方法/属性名称中替换Output
。
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. 该技术基于一些MSDN代码。 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.
直到此任务返回后才会更新。
// 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();
}
What's going on here is that Visual Studio is displaying the debug output from the program in the Output Window. 这里发生的是Visual Studio在输出窗口中显示程序的调试输出。 That is: if you use Trace.WriteLine, it'll appear in the Output Window, because of the default trace listener.
即:如果使用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. 它不会对子进程执行相同的操作,除非您明确捕获输出并将其与输出一起重定向。
Have you considered using a DefaultTraceListener ? 您是否考虑过使用DefaultTraceListener ?
//Create and add a new default trace listener.
DefaultTraceListener defaultListener;
defaultListener = new DefaultTraceListener();
Trace.Listeners.Add(defaultListener);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.