Mysterious Errors When Using Form Regions from Managed Code Add-ins

I've been noticing some feedback lately where a number of developers were having problems working with the controls on their form region.  Usually, these problems manifested as Outlook's object model returning null values back when trying to access the Controls collection of the UserForm object in the Microsoft Forms 2.0 library (which was accessed from the FormRegion.Form property).

This can be especially frustrating, because it looks like you've done everything right, and Outlook is just giving you back something that is totally wrong. Turns out, that isn't quite the case.

If you've added a reference to the 'Microsoft Forms 2.0' type library, you might have added the wrong reference to your project. On some computers, you'll find two different listings for the forms type library in the Add Reference dialog:

Depending on which reference you select, you'll either get a reference properly associated with the Primary Interop Assembly provided by Office, or you'll get a reference with a Visual Studio generated interop assembly. Unfortuatnely, the VS generated interop assembly incorrectly maps some elements of the type library to elements in the interop assembly.  This ultimately means that when you are using this reference, you'll end up calling into a different property or method than your code appears to be calling, which causes various strange exceptions and errors.

You can easily determine which reference you are using by selecting the reference and looking at the properties of the reference. If you've added the self-generated IA reference, the properties will look like this:

Notice that the reference has "Copy Local" set to True, and that the Path is not pointing at the Global Assembly Cache (GAC) but rather to the location of my solution.  This indicates that I'm using a self-generated interop assembly, and that I may be running into issues.

If you've added the correct reference to the PIA, then you'll see properties that look like this instead:

This time around, you'll see the Path is pointing into the GAC, and the "Copy Local" property is False. This indicates the PIA is being used, and everything should work normally.

If you find your project is using the incorrect reference, you should remove the reference and add a new reference.  Unforutnately, there is no way to determine which reference is the "right" reference from the Add References dialog.  You'll simply need to use trial and error and double check after adding the resource to make sure you've picked the right one.

The Take-away: Make sure you are using the right interop assembly when working with custom forms or form regions from your managed code solution.  Using the Visual Studio generated interop assembly can cause mysterious errors in your solution that you may not catch right away.