使用进程 c# 处理错误

Che*_*ani 3 c# error-handling process console-application

我使用 C# 创建了一个控制台应用程序,并使用Process.

以下是我的控制台应用程序代码

   static void Main(string[] args)
        {
            try
            {
                // ...my code
            }
            catch (Exception)
            {

                throw;
            }
        }
Run Code Online (Sandbox Code Playgroud)

下面是使用进程从窗口应用程序调用控制台应用程序的 exe 的代码

    public void CallExe()
    {
        try
        {                              
            Process proc = new Process();
            proc.StartInfo.FileName = @"D:\Debug\console1.exe";
            proc.StartInfo.Arguments = "My args";
            proc.StartInfo.CreateNoWindow = true;
            proc.StartInfo.RedirectStandardError = true;
            proc.StartInfo.RedirectStandardOutput = true;
            proc.StartInfo.UseShellExecute = false;
            proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            proc.Start();              
            proc.WaitForExit();              
            string stdout = proc.StandardOutput.ReadToEnd();
            string stderr = proc.StandardError.ReadToEnd();
            proc = null;
        }

        catch (Exception ex)
        {

            throw ex;
        }
    }
Run Code Online (Sandbox Code Playgroud)

现在,我想要的是当任何错误来自控制台应用程序时,它直接抛出到我的窗口应用程序 catch 块。或者我可以收到控制台应用程序抛出的窗口应用程序的错误消息吗?

ren*_*ene 5

您没有从您运行的进程中捕获任何内容。您不能同时调用ReadToEnd两个流,因为它会阻止一个或另一个流产生结果。如果要将标准输出捕获为标准错误,则需要订阅DataReceived事件并存储来自事件参数的数据。

Windows 窗体应用程序中的以下代码应如下所示:

Process proc = new Process();
proc.StartInfo.FileName = @"console.exe";
proc.StartInfo.Arguments = "My args";
proc.StartInfo.CreateNoWindow = false;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

//store outcome of process
var errors = new StringBuilder();
var output = new StringBuilder();
var hadErrors = false;

// raise events
proc.EnableRaisingEvents = true;

// capture normal output
proc.OutputDataReceived += (s, d) => { 
    output.Append(d.Data); 
};

// Capture error output
proc.ErrorDataReceived += (s, d) => { 
    if (!hadErrors)
    {
        hadErrors = !String.IsNullOrEmpty(d.Data);
    }
    errors.Append(d.Data); 
};

proc.Start();
// start listening on the stream
proc.BeginErrorReadLine();
proc.BeginOutputReadLine();

proc.WaitForExit();
string stdout = output.ToString();
string stderr = errors.ToString();

if (proc.ExitCode !=0 || hadErrors)
{
    MessageBox.Show("error:" + stderr);
}
Run Code Online (Sandbox Code Playgroud)

在测试控制台应用程序中,如果您愿意,您现在可以写入 stderr 并设置退出代码:

try
{
    Console.WriteLine("Ready ...");
    var cmd = Console.ReadLine();
    if (cmd == "e")
    {
        throw new Exception("boom");
    } else
    {
        Console.WriteLine("success!");
    }
    Environment.ExitCode = 0;
}
catch(Exception e)
{
    // write to stderr
    Console.Error.WriteLine(e.Message);
    // exit code to 1
    Environment.ExitCode = 1;
}
Run Code Online (Sandbox Code Playgroud)