Using Micro Eye AddInMon in an Outlook COM Add-in
AddInMon resolves a basic problem in Outlook COM Add-in development. Any Outlook COM Add-in must be able to detect when Outlook is shutting down so that the Add-in can release its references and not cause Outlook to remain in memory. The OnDisconnection event is not useful for this purpose since it may not fire if an Add-in has instantiated any Outlook objects. The accepted workaround has been to trap the Explorer and Inspector Close events and evaluate Explorers.Count and Inspectors.Count to detect when Outlook is closing. This approach requires that an Add-in does not load during the OnConnection event if Explorers.Count = 0. An Outlook Explorer is an object model representation of Outlook's main window. If an Add-in loaded when Explorers.Count = 0, it would not be possible to use the Explorer Close event to determine when Outlook shuts down. For a brief explanation of the problem, see the following Microsoft Knowledge Base articles:
If the Add-in did initialize its objects when there was no Outlook UI, there would be no Explorer Close or Inspector Close events that would alert the Add-in to an Outlook shutdown so it could properly clean up its own objects
Microsoft ActiveSync® 3.5 or above and similar programs break this workaround. ActiveSync synchronizes Outlook items with a Windows Mobile device. Version 3.5 and above typically instantiate an Outlook Application object with no user interface (UI) when Windows starts and keep it running until Windows shuts down. Only a subset of Outlook's working set loads into memory at this point, but the OnConnection event fires for COM Add-ins. If a user or other application later launches Outlook with full UI OnConnection does not fire again.
If ActiveSync loads during startup and launches Outlook with no UI then a COM Add-in that uses Explorers.Count to determine when to load will detect Outlook without UI and not initialize its own objects. When the user subsequently launches Outlook and opens an Explorer there will not be any new Connection event to cause the Add-in to reinitialize. As a result the Add-in will appear to fail when ActiveSync loads before Outlook.
This Microsoft Knowledge Base article contains additional information:
Note: The KB article above (Q329098) describes a fix related to this issue that first appeared in Outlook 2002 SP-3. We have tested this with our own Add-ins and haven't found any difference in load behavior when Outlook is launched without UI. If your design is different you may have different results.
AddInMon is an executable that provides a solution to this issue. AddInMon.exe monitors the Windows messages associated with Outlook's thread to detect when UI is instantiated. If that occurs, the EXE will disconnect and then connect any Add-ins set to load on startup that have an AddInMon value in the Windows registry. Disconnecting and then connecting the Add-in causes the Add-in to properly initialize its objects.
Micro Eye developed AddInMon for our own Add-ins. We subsequently decided to make it available to the Outlook development community to handle this common problem. You are free to use the executable and the code below as you see fit with the understanding that it is not supported or warranted in any way. Micro Eye, Inc. assumes no responsibility for this software in any commercial or non-commercial product or use.
Your installation program or code in the Add-in's OnConnection event must add a registry value named AddInMon. This value can be added under HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE depending upon where your Add-in is registered. The DWORD AddInMon is located under
where ProgID represents the Programmatic Identifier of the COM Add-in. The actual value of AddInMon is inconsequential - any numeric value will work. Figure 1 shows AddInMon under the key for an Add-In with the ProgID TestTrustAddin.Connect.
Figure 1. AddInMon key in the Windows Registry
Note: If you add a WriteDiagnostics DWORD value under the ProgID of your Add-in, you will cause AddInMon to write a diagnostics file named AddInMon.log to the Temp folder. This log file can be used to debug the operation of AddInMon with your Add-in. You should only enable the WriteDiagnostics DWORD when you are testing your Add-in with AddInMon. Like the AddInMon value shown above, the actual value of WriteDiagnostics is inconsequential. Sample content for AddInMon.log is shown in Figure 2.
Figure 2. AddInMon Log enabled with WriteDiagnostics
The following sample code shows how to implement AddInMon.exe in your solution. Your Setup program or your Add-in itself must write the AddInMon key to the correct location in the Registry. The OnConnection sample code requires two additional declarations for GetCurrentProcessID and GetCurrentThreadID and a conditional evaluation in the OnConnection event. An additional code module named modProcess contains the IsAddInMonProcess procedure to determine whether AddInMon is already loaded in memory. IsAddInMonProcess is called on the OnConnection code that launches AddInMon. You must add modProcess to your solution. If AddInMon.exe is not running and Outlook has started without UI, then AddInMon.exe is launched with a Shell statement. AddInMon requires three arguments: ProgID of your Add-in, ProcessID of Outlook, and ThreadID of Outlook. Since your Add-in runs in the Outlook process, Calling GetCurrentProcessID and GetCurrentThreadID returns values that pertain to Outlook. Provided that your installation program has written the AddInMon key to the correct location in the Windows Registry, AddInMon.exe will disconnect your Add-in immediately and then reconnect it if Outlook subsequently launches with UI. AddInMon.exe unloads itself from memory whenever the Outlook process unloads. If more than one Add-in has been registered with the AddInMon key, the first one to load will launch AddInMon.exe and then be disconnected. The next Add-in to load will also Shell AddInMon.exe, but the executable will shut itself down immediately if it detects an existing running instance of itself.
This modification to your OnConnection code is required for correct operation of AddInMon. Be aware that for correct Outlook shutdown you must write code in the Close event of event-aware Inspector and Explorer objects. For a complete example, see the Outlook COM Add-in Template.
The code for modProcess is shown below and is also provided for you convenience in the download for AddInMon. modProcess contains the IsAddInMonProcess procedure that determines whether AddInMon has already been loaded into memory. IsAddInMonProcess is called from the OnConnection procedure shown above.
To deploy AddInMon in your solution, your setup package should install AddInMon.exe in your application folder. No other support files are required for AddInMon.exe. If multiple applications use AddInMon, the first Add-in to load will call AddInMon and that instance of AddInMon will look for Outlook starting with UI. Multiple instances of AddInMon.exe are not allowed and are not required. You should modify your Add-in to use the OnConnection code shown above and redistribute a new version of your Add-in.
AddInMon is a freeware contribution by Micro Eye, Inc. to the Outlook development community. It is unsupported by Micro Eye. It is your responsibility to thoroughly test AddInMon before including it any solution that you distribute to others.
Current Version: 220.127.116.116
Last updated 12/21/04 to reduce the polling frequency. This handled a report of AddInMon interfering with the launch of an unrelated application.
Previous update 4/8/2004 to fix a bug that could disconnect the calling add-in. Revised to improve shutdown behavior in Outlook 2003, with help from Ken Slovak of Slovak Technical Services.
Digital Signature: Micro Eye, Inc.
Click Here to Download AddInMon.