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

发布于 2024-09-18 10:04:47 字数 415 浏览 7 评论 0原文

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

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

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

有办法做到这一点吗?

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


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

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

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).

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 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.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

肤浅与狂妄 2024-09-25 10:04:47
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 即可。

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.

森林很绿却致人迷途 2024-09-25 10:04:47

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

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

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.

// 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();
}
俯瞰星空 2024-09-25 10:04:47

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

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

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

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.

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.

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

献世佛 2024-09-25 10:04:47

您是否考虑过使用 DefaultTraceListener

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

Have you considered using a DefaultTraceListener ?

    //Create and add a new default trace listener.
    DefaultTraceListener defaultListener;
    defaultListener = new DefaultTraceListener();
    Trace.Listeners.Add(defaultListener);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文