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

前端 未结 4 1868
孤独总比滥情好
孤独总比滥情好 2020-12-06 01:37

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

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

What I would like

相关标签:
4条回答
  • 2020-12-06 01:44

    Have you considered using a DefaultTraceListener ?

        //Create and add a new default trace listener.
        DefaultTraceListener defaultListener;
        defaultListener = new DefaultTraceListener();
        Trace.Listeners.Add(defaultListener);
    
    0 讨论(0)
  • 2020-12-06 01:54
    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.

    0 讨论(0)
  • 2020-12-06 01:54

    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.

    0 讨论(0)
  • 2020-12-06 01:55

    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();
    }
    
    0 讨论(0)
提交回复
热议问题