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?
Your addin cannot run without Helpers.dll Because it works across AppDomain boundaries, the addin needs it own set of DLLs to be loaded into its own AppDomain.
If you don't need cross AppDomain functionality, you can use Token.Activate<AddInHostView>(AppDomain.CurrentDomain)
to load it if you have helpers.dll referenced in your host project.
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 :-)
精彩评论