捕获另一个进程的未处理异常

18

我想知道是否可以捕获使用Process.Start(...)启动的另一个进程抛出的未处理异常。

我知道可以使用link捕获标准错误,但我想要捕获通常由.net环境的Just In Time调试器捕获的错误,窗口显示以下内容: “您的应用程序发生了未处理的异常。如果选择继续,则应用程序将忽略此错误并尝试继续运行。如果选择退出,则应用程序将立即关闭....” 随后是异常消息和“继续”和“退出”按钮。


我希望找出是否可以以某种方式接入其他正在运行的进程的代码,并向AppDomain.UnhandledException事件添加事件处理程序。谢谢大家的帮助。 - Ahmad Hajou
我认为你是对的,没有问题有完全定制的解决方案。不过还是值得一试的。 - Ahmad Hajou
5个回答

12
你可以尝试这样做,以避免调试器问题的出现,你将不会收到异常,只有退出代码:

您可以尝试类似于这样的方法,以避免调试器问题的出现。这样做可以让您获得退出代码,而不是异常提示。

class Program
{
    static void Main(string[] args)
    {
        try
        {
            ProcessStartInfo info = 
                 new ProcessStartInfo("ErroneusApp.exe");
            info.ErrorDialog = false;
            info.RedirectStandardError = true;
            info.RedirectStandardOutput = true;
            info.CreateNoWindow = true;
            info.UseShellExecute = false;

            System.Diagnostics.Process p = 
                System.Diagnostics.Process.Start(info);
            p.EnableRaisingEvents = true;
            p.Exited += p_Exited;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        Console.ReadLine();
    }


    static void p_Exited(object sender, EventArgs e)
    {
        Process p = sender as Process;
        if (p != null)
        {
            Console.WriteLine("Exited with code:{0} ", p.ExitCode);
        }
        else
            Console.WriteLine("exited");
    }

}

这个问题中,他们提供了另一种解决方法,但需要更改一些注册表值。


我不认为这是我正在寻找的东西,无论如何感谢你的帮助。 - Ahmad Hajou
如何在UNC文件夹中调用BAT脚本? - Kiquenet

8

如果您要调用一个.Net可执行程序集,您可以加载它,并(自行承担风险 :D)在try_catch语句中调用Program类的Main方法:

Assembly assembly = Assembly.LoadFrom("ErroneusApp.exe");
Type[] types= assembly.GetTypes();
foreach (Type t in types)
{
 MethodInfo method = t.GetMethod("Main",
     BindingFlags.Static | BindingFlags.NonPublic);
 if (method != null)
 {
    try
    {
        method.Invoke(null, null);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
    break;
 }
}

但请注意,这样做会引入安全风险。

我认为这正是我目前正在寻找的确切答案。非常感谢您。附言:在我的实现中,我想将新加载的程序集添加到一个新的AppDomain中。 - Ahmad Hajou
我得在这里问一下,有没有办法找出exe是否是.NET可执行程序集?如果一个应用程序是在.NET 2.0下,而另一个是3.5,那会有影响吗? - Ahmad Hajou
我尝试使用GetConstructor()方法调用构造函数,但是它对我不起作用。您能否分享一些想法或示例代码来实现这个功能? - Kathir Subramaniam

2
不可以。如果受控应用程序使用了 standardError 和返回代码,您可能会收到错误或异常的通知,但无法以任何方式捕获它。

1

不必像jmservera的回答那样在程序集中四处潜行寻找Main方法,你可以在新域中执行程序集。请参阅此MSDN文章


0
在解决之前的目标调用问题时,最终我采用了以下方法。
您的某些应用程序可能具有当前目录中的依赖项,这会导致在另一个目录中执行时出现异常,因为依赖项不匹配。
Assembly assembly = Assembly.LoadFrom(file);
                    Directory.SetCurrentDirectory(Path.GetDirectoryName(file));
                    Type[] types = assembly.GetTypes();
                    foreach (Type t in types)
                    {
                        MethodInfo method = t.GetMethod("Main", BindingFlags.Static | BindingFlags.NonPublic);
                        if (method != null)
                        {
                            try
                            {
                              method.Invoke(null, null);
                            }

Directory.SetCurrentDirectory(Path.GetDirectoryName(file)); //通过引用当前目录目标调用异常将被解决。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接