locked
catch another process unhandled exception RRS feed

  • Question

  • 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 i wish to catch the error that are usually caught by the Just In Time debugger u know 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.

    Thanks in advance.
    Tuesday, February 16, 2010 9:04 AM

Answers

  • I was wondering if we can build up on that.

    Is there a way to check if the code is under .net or not?
    Can i find up which version of .net it's built upon?
    Can I load an assembly compiled on a different .net version than the one im using?

    ok  the  answer for  the first  question  is too  easy 
    when  you  try  this  code  you will  be able  to  check  if  the  assmbly  loaded  is under .net or not  after  doing  some probing 
     try
                {
                    Assembly asseDll = Assembly.LoadFrom("c:\\kernel32.dll");
                }
                catch(BadImageFormatException  badFormatException)  
                 {
    //here  will be generated an  exception  saying  that  
    //Could not load file or assembly 'file: / / / c: \\kernel32.dll' or one of its dependencies. The form should contain an assembly manifest.
                    
                    
                 }
    for  the second  question    : 
    you  can  do  this  checks 
      static void Main(string[] args)
            {
                Assembly assembly = Assembly.LoadFrom("C:\\assembTest.exe");                        
                         
                AssemblyName[] assemblies = assembly.GetReferencedAssemblies();
                if (assembly.ImageRuntimeVersion == "v2.0.50727")
                {
                    //here the problem derive from the fact that the framework runtime is the some for the 2.0 3.0 3.5
                    //so we must check for an assembly that must be referenced in order to target 
                    bool found = false;  
                    foreach (AssemblyName assName in assemblies)
                    {
                        if (assName.Name == "System.Core")
                        {
                            //then  the framework 3.5  is required                      
                            found = true;  
                            break;
                        }
                        else if (assName.Name == "WindowsBase" || assName.Name == "PresentationFramework")
                        {
                            //then  the  framework 3.0  is required   
                            found = true;  
                            break;
                        }
                                            
                    }
                    if (!found)
                    {
                        //then  the framework required is 2.0  
                    }
                }
                else if (assembly.ImageRuntimeVersion  == "v1.1.4322")
                {
                    //here  the framework 1.1  is required   
                    
                }
    Hope this can  help  you any way  any other ideas are welcome

    A man's dreams are an index to his greatness
    • Proposed as answer by BRAHIM kamel Friday, February 26, 2010 8:36 AM
    • Marked as answer by Ahmad Hajou Friday, February 26, 2010 5:41 PM
    Wednesday, February 24, 2010 4:04 PM
  • I afraid if it's possible because when Process.Start run the process, you can't access it's AppDomain. in other word, caller and callee processes are in different isolated areas by their domains. so you can't inject new code to it for handling unhandled exceptions.

    Nevertheless you can create a new domain and run the application on it using AppDomain.ExecuteAssembly
    using System;
    using System.IO;
    using System.Collections.Generic;
    
    class Program
    {
        static void Main(string[] args)
        {
          AppDomain newDomain=  AppDomain.CreateDomain("new domain");
            try
            {
                newDomain.ExecuteAssembly("yourApplicatin.exe");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadKey();
            }
        }
    }
    


    My Blog - MSDN Complement by providing Visual C# Walkthroughs and Sample Codes - Founded In February 24, 2010
    • Marked as answer by Ahmad Hajou Friday, February 26, 2010 5:40 PM
    Friday, February 26, 2010 11:13 AM

All replies

  • Come on Guys some one must have an answer to this?

    Am i in the wrong post?
    Wednesday, February 17, 2010 7:25 AM
  • ok  one work  arround that may be usefull it's  to try the  producer  consumer approach  at  a  process  level   somthing like this  : 
     1-take  a  look  at this  link (this  article illustrate a "bunch" of techniques   for Interprocess Synchronization and Communication)
    2-you  must  this  two  events  in  each  process 

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication1
    {
        static class Program
        {
            /// <summary>
            /// Punto di ingresso principale dell'applicazione.
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
                AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
                Application.Run(new Form1());
            }
    
            static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
            {
               //and here  is the last hope  to  catch  the exception 
                //here you must  add  your  way  to  communicate  the  stack  exception  to  the second  process  
            }
    
            static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
            {
                //and  here  you  must  add  your  way  to  communicate  the stack   exception  to  the second  process  
            }
        }
    }
    

    A man's dreams are an index to his greatness
    Wednesday, February 17, 2010 8:18 AM
  • That would be one way to do it.
    What i'm after is a way for no integration between the launching application and the application launched.

    Perhaps if there is a way to tap into the main application domain of the process and add an event handler to the AppDomain.UnhandledException event.

    10x for the support.
    Wednesday, February 17, 2010 10:45 AM
  • The solution to the above issue was to load the given assembly and execute the Main method through reflection. This was answered through this post .
    Tuesday, February 23, 2010 9:20 AM
  • thanks  for  the  response 
    A man's dreams are an index to his greatness
    Tuesday, February 23, 2010 9:36 AM
  • I was wondering if we can build up on that.

    Is there a way to check if the code is under .net or not?
    Can i find up which version of .net it's built upon?
    Can I load an assembly compiled on a different .net version than the one im using?
    Tuesday, February 23, 2010 9:45 AM
  • Hi,

    This example shows you how to extract the assembly version from an assembly which name we know:

    Assembly assembly = Assembly.LoadFrom("MyAssembly.dll");

    Version ver = assembly.GetName().Version;
    A BadImageFormatException will be thrown if:

    Version 2.0 or later of the common language runtime is currently loaded and assemblyFile was compiled with a later version.

    Harry


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Wednesday, February 24, 2010 4:59 AM
  • What im looking for is not the assembly version of the assembly being loaded, but the version of .net under which the assembly is compiled.

    I don't even know if i can load an assembly compiled with a different version of .net.

    That was my question, please let me know if it is still not clear.

    Thanks for the help.
    Wednesday, February 24, 2010 9:49 AM
  • I was wondering if we can build up on that.

    Is there a way to check if the code is under .net or not?
    Can i find up which version of .net it's built upon?
    Can I load an assembly compiled on a different .net version than the one im using?

    ok  the  answer for  the first  question  is too  easy 
    when  you  try  this  code  you will  be able  to  check  if  the  assmbly  loaded  is under .net or not  after  doing  some probing 
     try
                {
                    Assembly asseDll = Assembly.LoadFrom("c:\\kernel32.dll");
                }
                catch(BadImageFormatException  badFormatException)  
                 {
    //here  will be generated an  exception  saying  that  
    //Could not load file or assembly 'file: / / / c: \\kernel32.dll' or one of its dependencies. The form should contain an assembly manifest.
                    
                    
                 }
    for  the second  question    : 
    you  can  do  this  checks 
      static void Main(string[] args)
            {
                Assembly assembly = Assembly.LoadFrom("C:\\assembTest.exe");                        
                         
                AssemblyName[] assemblies = assembly.GetReferencedAssemblies();
                if (assembly.ImageRuntimeVersion == "v2.0.50727")
                {
                    //here the problem derive from the fact that the framework runtime is the some for the 2.0 3.0 3.5
                    //so we must check for an assembly that must be referenced in order to target 
                    bool found = false;  
                    foreach (AssemblyName assName in assemblies)
                    {
                        if (assName.Name == "System.Core")
                        {
                            //then  the framework 3.5  is required                      
                            found = true;  
                            break;
                        }
                        else if (assName.Name == "WindowsBase" || assName.Name == "PresentationFramework")
                        {
                            //then  the  framework 3.0  is required   
                            found = true;  
                            break;
                        }
                                            
                    }
                    if (!found)
                    {
                        //then  the framework required is 2.0  
                    }
                }
                else if (assembly.ImageRuntimeVersion  == "v1.1.4322")
                {
                    //here  the framework 1.1  is required   
                    
                }
    Hope this can  help  you any way  any other ideas are welcome

    A man's dreams are an index to his greatness
    • Proposed as answer by BRAHIM kamel Friday, February 26, 2010 8:36 AM
    • Marked as answer by Ahmad Hajou Friday, February 26, 2010 5:41 PM
    Wednesday, February 24, 2010 4:04 PM
  •  here  an example of link  where u  can find  this   http://www.dnzone.com/go?975 
    A man's dreams are an index to his greatness
    Wednesday, February 24, 2010 4:08 PM
  • Just because you can doesn't mean you should. When something is really awkward or difficult to implement you should ask yourself if your heading north in the southbound lane.


    BrianMackey.NET
    Wednesday, February 24, 2010 4:54 PM
  • what's this  Philosophical or proverb ?sage...!
    A man's dreams are an index to his greatness
    Friday, February 26, 2010 8:35 AM
  • I afraid if it's possible because when Process.Start run the process, you can't access it's AppDomain. in other word, caller and callee processes are in different isolated areas by their domains. so you can't inject new code to it for handling unhandled exceptions.

    Nevertheless you can create a new domain and run the application on it using AppDomain.ExecuteAssembly
    using System;
    using System.IO;
    using System.Collections.Generic;
    
    class Program
    {
        static void Main(string[] args)
        {
          AppDomain newDomain=  AppDomain.CreateDomain("new domain");
            try
            {
                newDomain.ExecuteAssembly("yourApplicatin.exe");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadKey();
            }
        }
    }
    


    My Blog - MSDN Complement by providing Visual C# Walkthroughs and Sample Codes - Founded In February 24, 2010
    • Marked as answer by Ahmad Hajou Friday, February 26, 2010 5:40 PM
    Friday, February 26, 2010 11:13 AM
  • what's this  Philosophical or proverb ?sage...!
    A man's dreams are an index to his greatness

    Lookup swallowing exceptions.  I worked @ a helpdesk for several years before I became a programmer.  This gave me a perspective that far to few programmers have or are willing to recognize.   If you ever got a call from a user asking why their program is performing ODD_BEHAVIOR_X and had to dig through piles of logs or event viewer junk you will learn to appreciate the importance of exceptions.

    This dude needs to fix the issue causing the exception.  Don't teach him how to create a terribad user experience.
    BrianMackey.NET
    Friday, February 26, 2010 3:09 PM
  • That is just perfect for my case.

    Thanks alot Sir.
    Friday, February 26, 2010 5:44 PM