使用进程错误处理c# [英] Error handling using process c#

查看:156
本文介绍了使用进程错误处理c#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用C#创建了一个控制台应用程序,并且使用 Process 从另一个Windows Forms应用程序中调用它。



以下是我的Console应用程序的代码

  static void Main(string [] args)
{
尝试
{
// ...我的代码
}
catch(异常)
{

throw;
}
}

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

  public void CallExe()
{
try
{
进程proc = new Process();
proc.StartInfo.FileName = @D:\Debug\console1.exe;
proc.StartInfo.Arguments =我的参数;
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;
}
}

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

解决方案

您没有从进程中捕获任何内容你跑。您不能在两个流上调用 ReadToEnd ,因为它会阻止一个或另一个生成结果。如果要将stdout同时捕​​获为stderr,则需要订阅 DataReceived 事件并存储事件参数中的数据。



您窗体中的以下代码表单应用程序应该如下所示:

  Process proc = new Process(); 
proc.StartInfo.FileName = @console.exe;
proc.StartInfo.Arguments =我的参数;
proc.StartInfo.CreateNoWindow = false;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

//存储进程结果
var errors = new StringBuilder();
var output = new StringBuilder();
var hadErrors = false;

// raise events
proc.EnableRaisingEvents = true;

//捕获正常输出
proc.OutputDataReceived + =(s,d)=> {
output.Append(d.Data);
};

//捕获错误输出
proc.ErrorDataReceived + =(s,d)=> {
if(!hadErrors)
{
hadErrors =!String.IsNullOrEmpty(d.Data);
}
errors.Append(d.Data);
};

proc.Start();
//开始侦听流
proc.BeginErrorReadLine();
proc.BeginOutputReadLine();

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

if(proc.ExitCode!= 0 || hadErrors)
{
MessageBox.Show(error:+ stderr);
}

在测试控制台应用程序中,您现在可以写入stderr并设置一个Exitcode if你喜欢:

  try 
{
Console.WriteLine(Ready ...);
var cmd = Console.ReadLine();
if(cmd ==e)
{
throw new Exception(boom);
} else
{
Console.WriteLine(success!);
}
Environment.ExitCode = 0;
}
catch(异常e)
{
//写入stderr
Console.Error.WriteLine(e.Message);
//退出代码到1
Environment.ExitCode = 1;
}


I have created a console application using C#, and I called it from another Windows Forms application using Process.

Below is my code for Console Application

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

                throw;
            }
        }

Below is code for call the exe of Console application from the window application using process

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

Now, What I want is when any error comes from the console application it directly throws to my window application catch block. Or can I get error message to my window application which is thrown by console application ?

解决方案

You are not capturing anything from the process you run. You can't call ReadToEnd on both streams as it will block one or the other from producing results. If you want to capture both the stdout as stderr you'll need to subscribe to the DataReceived events and store the data from the event arguments.

The following code in your windows forms application should look like this:

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

In the test console application you can now write to stderr and set an Exitcode if you like:

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

这篇关于使用进程错误处理c#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆