Interaction Between Loaded Add-ins

Can you talk across add-ins? With the old IDTExtensibility2 model? With the new VSTO model?

COM Add-ins can be accessed (from any code that can talk to the host application’s OM) via the COMAddins collection property on the host Application object. The COMAddins object exposes 4 properties and 2 methods. The only really useful members are the Count property and the Item and Update methods. You use the Item method to get a specific COMAddin object from the collection (specified by either numeric index or ProgId string). You can use the Update method to refresh the collection from the registry.

The COMAddin object exposes 8 properties, of which only Connect and Object are interesting. Connect is used to connect or disconnect an add-in. Object represents the underlying add-in object – the idea here is that if you know the type of the add-in object (represented by the interface(s) that it implements), you can use the Object property to get to the add-in’s methods and properties.

User code that uses the COMAddins collection and COMAddin objects is very uncommon. The scenario where people have made use of these objects is typically when they have multiple add-ins that need to talk across to each other, or at least to determine whether each other is currently running. In some cases, people have written VBA code that talks to COM add-ins. If you want to talk across your own add-ins, the obvious question is ‘why don’t you combine them into one add-in?’ It should go without saying that talking across add-ins that you don’t own is questionable at best, and potentially dangerous, and potentially represents a security attack.

How is the situation different with VSTO IStartup add-ins as opposed to traditional IDTExtensibility2 add-ins? In the following discussion I’ll look at some of the tactical issues when trying to talk across add-ins, under the strong caveat that this is usually something you do not want to do.

One difference is that VSTO IStartup add-ins require explicit FullTrust CAS permissions before they are allowed to be loaded. Setting the Connect property on the COMAddin obviously really invokes the set_Connect method on the COMAddin object. Disconnecting will work because the code is already running. Connecting will require the target add-in to have been granted Execution permissions before it will be allowed to run. This should be in place for a correctly installed VSTO IStartup add-in (if it is registered, and therefore loadable, it should also have CAS policy).

If you’re in an IStartup add-in and you attempt to connect a traditional IDTExtensibility2 add-in that is not already connected, this will require at least Execution permissions on the target COMAddin. This will not normally be true for IDTExtensiblity2 add-ins, because there is historically no requirement for IDTExtensibility2 add-ins to have any CAS policy associated with them. Therefore this operation will fail. This is a positive security design feature. On the other hand, it may be confusing to developers that they can programmatically unload an IDTExtensiblity2 add-in from an IStartup add-in but not necessarily load it. To fix this is simply a matter of applying appropriate CAS policy for the IDTExtensibility2 add-in.

By the same token, attempting to invoke a method on an add-in will require that that add-in be granted whatever permissions it needs for its functionality. Assuming the add-in is already running, the CLR assumes it de facto has Execution permissions, but only Execution permissions, and this may not be enough for the operations that the add-in wishes to perform. VSTO IStartup add-ins will have explicit FullTrust permissions, but IDTExtensibility2 add-ins normally do not, and in that case appropriate CAS policy would need to be applied.

Also note that while you can invoke a method on an IDTExtensibility2 add-in (assuming appropriate CAS), you cannot currently cannot invoke a method on a VSTO IStartup add-in, because we do not yet expose the COMAddins.Object property. We’re considering making this property available in a later release – does anyone have any strong requirements either way?

 

BTW - in case you're wondering...

The Indefatigable Chris Kunicki started me blogging, and I've had my blog on the OfficeZealot site ever since. Of course it goes without saying that the OZ site is the best place to be, and I've been very happy there. So what am I doing over here? Well, this is just a trial - I believe in trying new things, so I'm having a bash at the MSDN blog site for a while. I'll keep all my old posts on OZ for now, and cross-link.