On this page

Wrapping Unhandled exceptions from a WinForm application

Ads

Navigation

Search

Categories

Clouds

Sql Server (5) .Net (16) .Net 2.0 (2) C# (3) @ff Topic (5) Architectural solutions (9) ASP (1) BDD (5) Blog related (8) database (2) Development process (8) Facebook (1) job interviews (1) Lessons (5) Life (12) Microsoft (5) IIS 6 (2) SPS (sharepoint server) (3) Drivers (1) Internet Explorer (2) Windows 2003 server (1) NightDuck (2) Performance (5) Security (9) Sql Server 2000 (4) Study (2) TDD (1) Threading (3) Under the hood (1) Web (1) Web services (1) XSS (6)

Archive

Blogroll

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

RSS 2.0 | Atom 1.0 | CDF

Send mail to the author(s) E-mail

Total Posts: 63
This Year: 0
This Month: 0
This Week: 0
Comments: 33

Sign In
Pick a theme:

 Sunday, March 04, 2007
Sunday, March 04, 2007 6:35:22 PM (GMT Standard Time, UTC+00:00) ( .Net | Architectural solutions | Threading )

couple weeks ago, my friend and co-worker, shani raba, presented me a problem.
they have some sealed application as an .exe file that throws some exceptions and crashes their application.

So, i Thought that is a good idea to wrap the targeted application with reflection, and catch the unhandled thrown exceptions.

to demonstrate this,
I've created an application with a button that throws an exception.

private void button1_Click(object sender, System.EventArgs e)
{
    throw new Exception("my Exception, need to be wrapped");
}

the next thing that we need to create is the wrapper.

so, creating a console application with this code should have solved the problem:

[STAThread]
static void Main(string[] args)
{

    Assembly assembly = Assembly.LoadFrom ("cashTester.exe");

    Type t = assembly.GetType("cashTester.Form1");
    object o = Activator.CreateInstance(t);
    try
    {
        Application.Run((Form)o);
    }
    catch(Exception ex)
    {
        Console.Write("exception was thrown : " + ex.Message);
    }
}

running this code in debug mode successfully catch the exception from the winform.
but, for some reason, in a normal run, this code won't catch the exception.

makes you wonder, huh ?

so i did some thinking, what on earth can make this phenomena ?
The answer is : Threads.
Yes, like it or not, but this is the subject that everyone tries to avoid it.
everyone knows it exists, and no one really likes it,
but we can't run from the problem, we need to confront it.

So, what can we do ?

since Application.Run launches a new thread, we can add to the Application.ThreadException event handler, an exception handling method.

like this class :

 

/// <summary>
/// The Wrapper class
/// </summary>
public class Wrapper
{

    /// <summary>
    /// Public cunstructor
    /// </summary>
    public Wrapper()
    {
    }

    /// <summary>
    /// This function will initialize the exception handling
    /// </summary>
    public void Init()
    {
        // define handlers for unhandled exceptions
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(this.exp);
        Application.ThreadException +=new System.Threading.ThreadExceptionEventHandler(this.ThreadExp);
    }

    /// <summary>
    /// This method is for the threads exceptions
    /// </summary>
    /// <param name="o">the object</param>
    /// <param name="args">Thread exception args</param>
    void ThreadExp(object o, System.Threading.ThreadExceptionEventArgs args)
    {
        // Write the message to the console
        Console.Write("Unhandled thread exception was thrown : " + args.Exception.Message);
    }

    /// <summary>
    /// This method is for the unhandled exceptions from the main thread
    /// </summary>
    /// <param name="o">the object</param>
    /// <param name="args">exception arguments</param>
    void exp(object o,System.UnhandledExceptionEventArgs args)
    {
        // Write the message to the console
        Console.Write("Unhandled exception was thrown : " + ((Exception)args.ExceptionObject).Message);
    }

    public void Run()
    {
        // Load the assembly
        Assembly assembly = Assembly.LoadFrom ("cashTester.exe");

        // get the type of the object
        Type t = assembly.GetType("cashTester.Form1");

        // invoke it
        object o = Activator.CreateInstance(t);

        // Run the application - note that this line starts an additional thread
        Application.Run((Form)o);
    }
}

 

now, all we need is to launch it :

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
    Wrapper w = new Wrapper();
    w.Init();
    w.Run();
}

 

now we got an exception wrapper for launching applications.

Shani, tell me if that helped ...

p.s.
There are more ways to do it, but this is the simplest one