Search code examples
c#wpfexceptionadd-inmaf

Catch Exception in AddInToken.Activate<T>()


I use MAF and I have a problem with activating the addin. Let me explain my plan.

First I create a secondary AppDomain then I try to activate the addin:

MyAddIn = Token.Activate<AddInHostView>(domain);

My AddIn is very simple and referenced only one helper assembly. If this helper assembly is in the directory of the AddIn, all things work like a charm.

AddIns

  • MyDemoAddIn.dll
  • Helpers.dll

If I delete the Helpers.dll the whole application crash:

A first chance exception of type 'System.IO.FileNotFoundException' occurred in MyDemoAddIn.DLL 'PresentationHost.exe' (Managed (v4.0.30319)): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\mscorlib.resources\v4.0_4.0.0.0_de_b77a5c561934e089\mscorlib.resources.dll' A first chance exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll A first chance exception of type 'System.Reflection.TargetInvocationException' occurred in System.AddIn.dll A first chance exception of type 'System.Reflection.TargetInvocationException' occurred in System.AddIn.dll

I tested all things with exception handling. I can't catch the exception from the Host, AddInView or my created AppDomain :-(

Does anyone have an idea?


Solution

  • The answer is easier than you think... The problem was a error in the Finalizer() Method from the AddInView.dll which is an interlayer of the MAF. Here is my solution.

    Demo (Host)

    try
    {
        MyAddIn = Token.Activate<AddInHostView>(domain);
    }
    catch (Exception ex)
    {
        try
        {
            AppDomain.Unload(domain);
            domain = null;
        }
        catch (ThreadAbortException threadAbortException)
        {
            //ToDo: Logging
        }
        catch (CannotUnloadAppDomainException cannotUnloadAppDomainException)
        {
            //ToDo: Logging
        }
        catch (Exception exception)
        {
            //ToDo: Logging
        }
    }
    

    AddInView

    [AddInBase]
    public class AddInView : UserControl
    {
        //Necessary constructor to handle the exception.
        //Normal constructor is not called when an error occurs at startup!!!
        static AddInView()
        {
            AppDomain.CurrentDomain.DomainUnload += CurrentDomain_DomainUnload;
        }
    
        //Normal constructor
        public AddInView()
        {
            //Do other things...
            //e.g. Dispatcher.UnhandledException += Dispatcher_UnhandledException;
        }
    
        static void CurrentDomain_DomainUnload(object sender, EventArgs e)
        {
            //To cleanup and stuff
        }
    }
    

    Now, if an error occurs (Activate<>) the exception handler catches the error (FileNotFound Helpers.dll not found) and unload the whole AppDomain without crash the main AppDomain :-)