Outlook Shutdown and COM Add-ins

Depending on how familiar you are with Outlook development, you may have seen previous versions of Outlook occasionally had a problem shutting down. Often there could be a catch-22 situation, where the add-in was waiting to hear from Outlook that it should clean up its references, and Outlook was waiting for these references to be released before notifying the add-ins that it was shutting down. In previous versions, Outlook only paid attention to the number of references for the OM objects, and not if those references were held by add-ins.

For Outlook 2007, our developers spent time investigating the problem, and came up with a fix that has caused the shutdown issues for Outlook to largely disappear, even when running managed code add-ins. There are, of course, a few limitations to what can be done, so it's important that Outlook add-in developers understand what this work buys them and what they still need to do to ensure an add-in solution doesn't keep Outlook alive.

Outlook now keeps track of references which it knows were handed out to an Outlook add-in. References provided to an add-in and those derived from objects provided to an add-in are tagged as belonging to that particular add-in. When the UI is closed and the only remaining references are tagged as blonging to add-ins, Outlook will shutdown. If a reference tagged for an add-in is marshaled out to another process, these references can be disconnected from under the application when Outlook shuts down.

There are a few scenarios through which Outlook can lose track of an add-in reference on an object. For instance, accessing Outlook objects through non-Outlook libraries, such as returning a reference to the Application object through the command bars OM (accessing properties like Application or Parent), can cause the context to be lost. We've done work to improve the way this works with some new Office APIs to make sure that the context is not lost. For example, when working with the ribbon UI integration, objects provided in ribbon callback methods will still be in the context of the add-in. Likewise, using the new Custom Task Pane OM provided by Office will not get you in trouble either.

Another possible scenario is if the add-in creates a new instance of the Application object (new Application() or calling CoCreateInstance) and then marshal this object (or derived objects) to another process or thread. Outlook will be unable to track these objects as belonging to an Outlook add-in. When the reference is marshaled to become a strong external reference, Outlook will not shut down properly until the reference is cleaned up. Technically speaking, Outlook will remain alive if there are external connections registered through the IExternalConnection interface of COM on any OM objects.

These changes to our shutdown logic apply only to add-ins and internal references. The behavior for COM callers outside of the Outlook process space hasn't changed. Programs that CoCreateInstance the Outlook Application object can expect that Outlook will remain alive, even if the user attempts to quit the process, until those references are released as long as these references appear to be external connections to Outlook.

The benefit of these changes should be pretty clear: COM add-ins will no longer need to implement some kind of shut down workaround which was previously a popular sight in any Outlook add-in code. The change also lowers the bar to writing a COM add-in that doesn't break Outlook. New Outlook developers won't need to know about any sort of hacks or workarounds to make sure Outlook shuts down in the appropriate way. They can rely on seeing the OnBeginShutdown and OnDisconnection methods be called as Outlook prepares to shutdown and actually shuts down.

Final note: Developers shouldn't use this as an opportunity to be lazy though. You should continue to write clean code that properly cleans up and releases your references whenever the add-in has finished using that object. Cleaning up references to Outlook objects is important for memory utilization and performance implications. Each OM object reference kept alive also requires Outlook to keep the internal representation of that item alive, including any server connections required by that object. This can produce exceptions under unexpected conditions that can be avoided by properly releasing these objects when the add-in is finished with the object.