将儿童过程的输出(Stdout,stderr)重定向到Visual Studio的输出窗口
-
30-09-2019 - |
题
目前,我正在从我的C#程序中启动批处理文件:
System.Diagnostics.Process.Start(@"DoSomeStuff.bat");
我想做的就是将该子过程的输出(Stdout和stderr)重定向到Visual Studio中的输出窗口(特别是Visual C#Express 2008)。
有没有办法做到这一点?
(另外:使其并非全部被缓冲,然后在孩子过程完成时吐出到输出窗口。)
(顺便说一句:目前我可以得到stdout(而不是stderr) 父母 通过使我的程序成为“ Windows应用程序”而不是“控制台应用程序”来出现在输出窗口中。如果该程序在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();
同样的想法 Error
, ,只需更换即可 Output
在这些方法/属性名称中。
其他提示
这种适用于我的变体 - 现在对此进行启动,因为我希望我能早点找到它。请注意,这只是从真实代码中提取的片段,因此可能存在微不足道的错误。
该技术基于一些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();
}
这里发生的事情是,Visual Studio正在输出窗口中显示程序的调试输出。也就是说:如果您使用Trace.Writeline,则由于默认跟踪侦听器,它将出现在输出窗口中。
不知何故,您的Windows表单应用程序(当使用Console.Writeline时;我假设您使用的是Console.Writeline)也在编写调试输出,而Visual Studio正在挑选此功能。
除非您明确捕获输出并将其与输出一起重定向,否则它不会对子过程做同样的事情。
您是否考虑过使用 DefaultTracelistener ?
//Create and add a new default trace listener.
DefaultTraceListener defaultListener;
defaultListener = new DefaultTraceListener();
Trace.Listeners.Add(defaultListener);
不隶属于 StackOverflow