18

I wish to know if i can catch the unhandled exceptions thrown by another process which I started using the Process.Start(...)

I know i can catch the standered error using this link , but what I want is to catch the error that are usually caught by the Just In Time debugger of the.net environment, the window with the following words: "An unhandled exception has occurred in your application . If you Continue, the application will ignore this error and attempt to continue . If you click Quit, the application will be shut down immediately ...." Which is then followed by the exception message and a "Continue" and "Quit" button.

Kiquenet
  • 14,494
  • 35
  • 148
  • 243
Ahmad Hajou
  • 1,289
  • 5
  • 22
  • 39
  • I wish to find out If i can somehow tap into the code of the other running process and add an event handler to the AppDomain.UnhandledException event. Thanks for the help guys – Ahmad Hajou Feb 17 '10 at 10:39
  • I think ur right, no problem has the exact customized solution. it's worth a shot though. – Ahmad Hajou Feb 18 '10 at 16:15

5 Answers5

12

You can try something like that to avoid the debugger question to appear, you won't get the exception but only the exit code:

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

}

In this question they provided another workaround for that, but changing some registry values.

Community
  • 1
  • 1
jmservera
  • 6,454
  • 2
  • 32
  • 45
8

If you are calling to a .Net executable assembly you can load it and (at your own risk :D ) call to the Main method of the Program class into a try_catch statement:

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

But be aware of the security risks you are introducing doing that.

jmservera
  • 6,454
  • 2
  • 32
  • 45
  • I think this is the exact answer I'm currently looking for Thank you very sir. P.S. in my implementation, i think im going to add the newly loaded assembly to a new AppDomain. – Ahmad Hajou Feb 18 '10 at 16:12
  • I gotta ask here, is there a way to find out if the exe is a .net executable assembly? what if the application is under .net 2.0 while the other is 3.5, will that matter? – Ahmad Hajou Feb 18 '10 at 16:14
  • I tried to invoke the constructor using GetConstructor() method. But it is not working for me. Could you please share an idea or sample code to achieve this? – Kathir Subramaniam May 31 '16 at 04:53
2

No. If the controlled app utilizes standardError and return codes you may be notified of the occurance of an error or exception but you cannot trap it in any way.

Sky Sanders
  • 36,396
  • 8
  • 69
  • 90
1

Instead of doing the whole sneaking around the assembly to try to find the Main method like in jmservera's answer, you can simply execute the assembly in a new domain. See this msdn article

Guillaume CR
  • 3,006
  • 1
  • 19
  • 31
0

In resolving to the previous target invocation issue, finally i end up with the below method.

Some of your application would have dependencies in the current directory, which leads to exception whenever it is executed in the another directory since the dependencies doesnt match.

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)); //by refering to the current directory target invocation exception would be resolved.

Ganesh
  • 1
  • 1
  • 8