'How to get the error message of a Process?

For vsinstr -coverage hello.exe, I can use the C# code as follows.

Process p = new Process(); 
StringBuilder sb = new StringBuilder("/COVERAGE "); 
sb.Append("hello.exe"); 
p.StartInfo.FileName = "vsinstr.exe"; 
p.StartInfo.Arguments = sb.ToString(); 
p.Start(); 
p.WaitForExit();

When there's an error, I get the error message : Error VSP1018: VSInstr does not support processing binaries that are already instrumented..

How can I get this error message with C#?

SOLVED

I could get the error messages from the answers.

using System;
using System.Text;
using System.Diagnostics;

// You must add a reference to Microsoft.VisualStudio.Coverage.Monitor.dll

namespace LvFpga
{
    class Cov2xml
    {
        static void Main(string[] args)
        {
            Process p = new Process();
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;         
            p.StartInfo.UseShellExecute = false; 

            StringBuilder sb = new StringBuilder("/COVERAGE ");
            sb.Append("helloclass.exe");
            p.StartInfo.FileName = "vsinstr.exe";
            p.StartInfo.Arguments = sb.ToString();
            p.Start();

            string stdoutx = p.StandardOutput.ReadToEnd();         
            string stderrx = p.StandardError.ReadToEnd();             
            p.WaitForExit();

            Console.WriteLine("Exit code : {0}", p.ExitCode);
            Console.WriteLine("Stdout : {0}", stdoutx);
            Console.WriteLine("Stderr : {0}", stderrx);
        }
    }
}


Solution 1:[1]

You need to redirect the standard output or standard error. Here's a code sample for stdout:

Process p = new Process();
p.StartInfo.FileName = "hello.exe";
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.Start();
string stdout = p.StandardOutput.ReadToEnd(); 
p.WaitForExit();

Solution 2:[2]

You have to redirect StdError and read the stream to catch the errors.

System.Diagnostics.ProcessStartInfo processStartInfo = 
    new System.Diagnostics.ProcessStartInfo("MyExe.exe", "parameters ...");
int exitCode = 0;
processStartInfo.RedirectStandardError = true;
processStartInfo.RedirectStandardOutput = true;
processStartInfo.CreateNoWindow = true;
processStartInfo.UseShellExecute = false;
System.Diagnostics.Process process =
System.Diagnostics.Process.Start(processStartInfo);

process.WaitForExit(); //wait for 20 sec
exitCode = process.ExitCode;
string stdout = process.StandardOutput.ReadToEnd();
string stderr = process.StandardError.ReadToEnd();

// you should see the error string in stdout or stderr depending 
// on how your console applicatione decided to output the failures.

Solution 3:[3]

You have to retrive standard/error output of called process. Here is how to do it:

standard output

error output

Solution 4:[4]

Assuming the vsinstr.exe process writes that error to the standard error stream you can get the error message by capturing the process's standard error stream. To do this you'll need to set the ProcessStartInfo class's RedirectStandardError property to true, add an event handler to the Process class's ErrorDataReceived event and call the Process class's BeginErrorReadLine method before starting the vsinstr.exe process.

Here's some sample code:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading;

class CaptureProcessOutput
{
    private ManualResetEvent m_processExited = new ManualResetEvent(false);
    private List<string> m_errorMessages = new List<string>();
    private List<string> m_regularMessages = new List<string>();
    private Process m_process = new Process(); 

    public CaptureProcessOutput()
    {
    }

    public void Run (string[] args)
    {
        StringBuilder sb = new StringBuilder("/COVERAGE "); 
        sb.Append("hello.exe"); 
        m_process.StartInfo.FileName = "vsinstr.exe"; 
        m_process.StartInfo.Arguments = sb.ToString(); 
        m_process.StartInfo.UseShellExecute = false;

        m_process.Exited += this.ProcessExited;

        m_process.StartInfo.RedirectStandardError = true;
        m_process.StartInfo.RedirectStandardOutput = true;

        m_process.ErrorDataReceived += this.ErrorDataHandler;
        m_process.OutputDataReceived += this.OutputDataHandler;

        m_process.BeginErrorReadLine();
        m_process.BeginOutputReadLine();

        m_process.Start();

        m_processExited.WaitOne();
    }

    private void ErrorDataHandler(object sender, DataReceivedEventArgs args)
    {
        string message = args.Data;

        if (message.StartsWith("Error"))
        {
            // The vsinstr.exe process reported an error
            m_errorMessages.Add(message);
        }
    }

    private void OutputDataHandler(object sender, DataReceivedEventArgs args)
    {
        string message = args.Data;

        m_regularMessages.Add(message);
    }

    private void ProcessExited(object sender, EventArgs args)
    {
        // This is where you can add some code to be
        // executed before this program exits.
        m_processExited.Set();
    }

    public static void Main (string[] args)
    {
        CaptureProcessOutput cpo = new CaptureProcessOutput();
        cpo.Run(args);
    }
}

Solution 5:[5]

Er -- inside a try/catch block? Am I missing something?

try
{

    Process p = new Process();
    StringBuilder sb = new StringBuilder("/COVERAGE ");
    sb.Append("hello.exe");
    p.StartInfo.FileName = "vsinstr.exe";
    p.StartInfo.Arguments = sb.ToString();
    p.Start(); 
    p.WaitForExit(); 

}
catch(Exception ex)
{
   // Handle exception
}

...keep in mind that the ex.Message may not contain the exeption that you specified above, while the inner exception, e.g. ex.InnerException may.

Solution 6:[6]

I'm assuming that you're seeing this message while debugging. Let me know if this wasn't exactly what you were looking for, but you could use a simple try catch block.

try
{
    //CODE GOES HERE
} catch (Exception ex)
{
    System.Diagnostics.Debug.WriteLine(ex.Message);
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mark Heath
Solution 2 yanckst
Solution 3 rotman
Solution 4 HairOfTheDog
Solution 5 George Johnston
Solution 6 GregB