【问题标题】:How to get the error message of a Process?如何使用 C# 获取错误消息
【发布时间】:2011-06-27 17:06:05
【问题描述】:

对于vsinstr -coverage hello.exe,我可以使用如下C#代码。

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();

出现错误时,我收到错误消息:Error VSP1018: VSInstr does not support processing binaries that are already instrumented.

如何使用 C# 获取此错误消息?

已解决

我可以从答案中得到错误信息。

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);
        }
    }
}

【问题讨论】:

  • 当心,正如@SliverNinja 在下面的评论中所说,阅读 p.StandardOutput.ReadToEnd() 和 p.StandardError.ReadToEnd() 可能会死锁。

标签: c# process


【解决方案1】:

我假设您在调试时看到此消息。如果这不是您想要的,请告诉我,但您可以使用简单的 try catch 块。

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

【讨论】:

    【解决方案2】:

    呃——在 try/catch 块内?我错过了什么吗?

    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
    }
    

    ...请记住,ex.Message 可能不包含您在上面指定的异常,而内部异常,例如ex.InnerException 可能。

    【讨论】:

    • 实际上,您确实错过了一些东西。该过程正确执行并退出。如果该过程中的某个程序确定它有错误,这也不例外。所以你不会因此而抓到任何东西。
    【解决方案3】:

    您必须重定向 StdError 并读取流以捕获错误。

    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.
    

    【讨论】:

    【解决方案4】:

    您必须检索被调用进程的标准/错误输出。这是怎么做的:

    standard output

    error output

    【讨论】:

      【解决方案5】:

      您需要重定向标准输出或标准错误。这是标准输出的代码示例:

      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();
      

      【讨论】:

        【解决方案6】:

        假设 vsinstr.exe 进程将该错误写入标准错误流,您可以通过捕获该进程的标准错误流来获取错误消息。为此,您需要将 ProcessStartInfo 类的 RedirectStandardError 属性设置为 true,向 Process 类的 ErrorDataReceived 事件添加一个事件处理程序,并在启动 vsinstr.exe 进程之前调用 Process 类的 BeginErrorReadLine 方法。

        这里有一些示例代码:

        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);
            }
        }
        

        【讨论】:

        • 我必须在m_process.BeginErrorReadLine(); 之前先启动该过程。否则它会抛出一个异常,说 RedirectStandardError 必须设置为 true,而它显然是.. 我猜是一个错误
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-14
        • 2022-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-23
        相关资源
        最近更新 更多