To make sure that only the shim is loading as an add-in and not both the
shim and your managed add-in, you need to either uninstall your old managed
add-in or go to the registry
(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\Outlook\Addins if you chose to
install for all users,
HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook\Addins if you chose to
install for the current user only) and remove the registry key created for your
non-shimmed add-in.
Another
thing that you will want to do
is turn off in the project settings in the Compile section the "Register
for COM Interop" option. Otherwise,
both your shim and your non shimmed add-in will keep registering themselves in
the registry.
I had to
verify that everything was loading as I expected--that is that all my stuff was
loading in its own appdomain.
To do this,
I launched Outlook with my add-in running and without the Visual Studio debugger
attached. Being the rocket scientist type, I fired up cordbg.exe. To
launch mscordbg, launch your .NET Framework SDK Command Prompt from your start
menu, programs, Microsoft .NET Framework SDK group. Then type "cd
bin". Then type cordbg.exe. I always then type ? to get a list of
commands because I can never remember them. I then typed "attachn
Outlook.exe" to attach to Outlook. Then I typed "ap" to list all the
appdomains. Sure enough, there was my add-in, in its own appdomain rather
than in default domain. You can then type "q" to exit cordbg.exe which
will also quit the Outlook process.\
Speaking of
Outlook, getting Outlook to shutdown when you write an add-in is pretty hard
right now. If you have outstanding references to Outlook OM objects (which
you almost always will) the Outlook add-in doesn't get shutdown because it is
waiting for you to release your Outlook OM objects before it shuts you
down. Yeah--it's wierd. The present recommendations that I see to
get around this is to listen to Explorer and Inspector close events and when you
detect that all the Explorer and Inspectors have closed down, you release all
your COM objects (just set all your COM objects you've held on to to null or
nothing, you may also force a GC.Collect()
GC.WaitForPendingFinalizers()). Then, you get OnDisconnection called
because Outlook is happy that you've released all your Outlook OM objects.
The problem is, you really shouldn't have to worry about this! You don't
have to in VSTO because we unload the appdomain thereby cleaning up any
references you may have had.
It would be
cool if someone wrote a modified add-in shim for Outlook that listened to these
Explorer and Inspector close events--ideally, this would just be built into the
existing C++ based shim wrapper. When the last Explorer or Inspector
closes, it could call OnDisconnection on the managed add-in's implementation of
IDTExtensibility2. The managed add-in wouldn't have to do the silly
setting of all COM objects to null because after OnDisconnection is called by on
the managed add-in by the shim, the shim would then unload the appdomain of the
add-in--thereby making Outlook happy because all the outstanding references used
by the add-in would be cleaned up. Then, Outlook would call the
OnDisconnection implementation provided by the shim. The shim would just
return immediately from this because it has already unloaded the actual managed
add-in. This would theoretically fix the nightmare that is Outlook
add-in development right now when it comes to getting the silly things to shut
down.