15

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

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

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

有没有办法做到这一点?

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


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

4

4 回答 4

24
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那些方法/属性名称。

于 2010-09-04T13:42:35.247 回答
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();
}
于 2011-08-31T21:35:21.983 回答
2

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

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

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

于 2010-09-04T13:11:56.433 回答
-5

您是否考虑过使用DefaultTraceListener

    //Create and add a new default trace listener.
    DefaultTraceListener defaultListener;
    defaultListener = new DefaultTraceListener();
    Trace.Listeners.Add(defaultListener);
于 2010-09-04T12:35:56.270 回答