Add-in Express™ for Microsoft® Office and .netAdd-in Express Home > Add-in Express for Office and .NET > Online Guide > COM add-in tips
COM add-in tips
On this page you will find some tips and tricks related to building Office add-ins in Visual Studio .NET: VB, C#, C++,
installing your add-in on Vista etc.
Add-in Express uses interfaces from the Office Type Library. We do not describe them here. Please refer to the VBA help and
application type libraries.
An exception when registering /unregistering the add-in
When your add-in is registered and unregistered, Add-in Express creates an instance of the module. Because in this
situation the module isn't loaded by the host application, you can't use any Office-related classes. If the code isn't
prepared for this, it will break. If it breaks when you uninstall the add-in, you'll have to clean the registry either
manually or using a registry cleaner program.
The same applies to class-level initializers; they are executed even before the module constructor is run.
To initialize your add-in, you need to use the AddinInitialize event of the module. It fires when Office loads the add-in.
Note, however, that for Ribbon-enabled Office applications, the first event that the module fires is OnRibbonBeforeCreate.
The add-in doesn't work
If your Office COM add-in does not work, check out:
The add-in is not registered,
An assembly required by your add-in cannot be loaded,
An exception at add-in start-up, and
Your add-in has fallen to Disabled Items.
The add-in is not registered
If LoadBehavior is 2, this may be an indication of an unhandled exception at add-in startup. Check Registry Keys.
An assembly required by your add-in cannot be loaded
Possible reasons are:
- the assembly is missing in the installer
- the user starting the host application doesn't have permissions for the folder where the add-in was installed; say,
a per-machine add-in is installed to a user's Application Data folder and another user loads the add-in
- the PublicKeyToken of your add-in assembly doesn't correspond to the PublicKeyToken mentioned in the Add-in Express Loader Manifest.
See How to find the PublicKeyToken of the add-in
An exception at add-in start-up
If an exception occurs in the constructor of the add-in module, or when module-level variables are initialized,
Office will interrupt the loading sequence and set LoadBehavior of your add-in to 2. See
Registry keys.
Your add-in has fallen to Disabled Items
If your add-in fires exceptions at startup or causes the host application to crash, the host application (or the end-user)
may block the add-in and move it to the Disabled Items list. To find the list, in Office 2000-2003, go to "Help", then "About".
At the bottom of the About dialog, there is the Disabled Items button. Check it to see if the add-in is listed there (if so,
select it and click Enable). In the Ribbon UI of Office 2007, you find that list on the Add-ins tab of the Office Menu |
{host application} Options dialog. In the Ribbon UI of Office 2010, the Add-ins tab can be found in the File | Options dialog.
After you get the Disabled Items dialog, you select the add-in and click Enable.
Delays at add-in start-up
If you use the WebViewPane layout of your custom Outlook forms, please check WebViewPane.
Try clearing the DLL cache, see Deploying add-ins – shadow copy.
Maybe you will be able to identify the source of the problem by turning off other COM add-ins and Smart Tags in the host application.
If your host application is Excel, turn off all Excel add-ins, too. You can also try turning off your antivirus software.
Also check Office 2003 Resource Kit
COM Add-ins dialog
In version 2007 of Word, Excel, PowerPoint and Access you click the Office Menu button, then click {Office application} options and
choose the Add-ins tab. Now choose COM Add-ins in the Manage dropdown and click Go. In all other Office applications, you need to add
the COM Add-ins command to a toolbar or menu of your choice. To do so, follow the steps below:
- Open the host application (Outlook, Excel, Word, etc.).
- On the Tools menu, click Customize.
- Click the Commands tab.
- In the Categories list, click the Tools category.
- In the Commands list, click COM Add-Ins and drag it to a toolbar or menu of your choice.
In Office 2000-2003, the COM Add-ins dialog shows only add-ins registered in HKCU. In Office 2007, HKLM-registered add-ins are
shown too. See also Registry Keys.
Project wizard options
The Isolation group box in the Add-in Express project wizard allows choosing the shim to be used with your add-in. To understand shims, see
Deploying Add-in Express projects. Check the "Configure the setup project for the standard user" checkbox, for your add-in to be installed by a non-admin user – it disables the "Everyone / Just Me" choice in the setup UI and targets the DefaultLocation property of the setup project to [AppDataFolder] instead of [ProgramFilesFolder]. If you check the "Enable UAC for the setup on Vista" checkbox, the setup will require administrative privileges to be asked, when run by a non-admin user on Vista. For VS2003 developers, these features are available with the following command lines:
%AddinExpressInstallFodler%\Bin\DisableUAC.exe %BuiltOuputPath% /UAC=On
%AddinExpressInstallFodler%\Bin\DisableUAC.exe %BuiltOuputPath% /UAC=Off
They emulate checking the "Configure for the standard user" and checking/clearing the "Enable UAC" checkboxes. % BuiltOuputPath% specifies
the path and file name of the MSI. "Add the Primary Interop Assemblies to the Project" adds a currently installed PIA(s)
(see What are PIAs?) to the project. "Use Version-neutral Office PIAs"
adds the PIAs supplied with Add-in Express installation package (see Version-neutral
interop assemblies?).
User Account Control (UAC) on Vista
The User Account Control (UAC) must be turned on for the Office 2007 add-in installed to HKCU (for the current user account only) to work.
For instance, if UAC is turned on, the user can turn the add-in on / off via the COM Add-ins dialog. Otherwise, Office 2007 will show your add-in
in this dialog but will not load the add-in.
Do not add any custom code to the Add-in Module Constructor
The add-in module is created when your add-in is installed. It also may be created when your add-in is uninstalled. It is strongly
recommended that you use any initialization code in the AddinInitialize event handler. Pay attention to module-level variables: they are initialized
even before the constructor is run, so move their initialization to AddinInitialize, too.
How to get access to the add-in's host applications
The add-in module provides the HostApplication property that returns the Application object (of the Object type) of the host application
the add-in is currently running in. For your convenience, the COM Add-in project wizard adds host-related properties to the add-in module, such as
OutlookApp and ExcelApp. To identify the host application, you can also use the HostName, HostType, and HostVersion properties of the module.
Commands of the Add-in Module
- Add CommandBar – adds a command bar to your add-in (see Command Bars: toolbars, menus,
and context menus)
- Add Main Menu – allows modifying the main menu of the host application (see
Command bar UI components)
- Add Context Menu – allows modifying context menus of the host application
- Add Explorer CommandBar – allows creating a custom toolbar or modifying an existing (or built-in) toolbar in Outlook Explorer windows
- Add Explorer Main Menu – allows modifying the main menu in Outlook Explorer windows
- Add Inspector CommandBar – allows creating a custom toolbar or modifying an existing (or built-in) toolbar in Outlook Inspector windows
- Add Inspector Main Menu – allows modifying the main menu in Outlook Inspector windows
- Add Built-in Control Connector – allows intercepting the action of a built-in control of the host application
(see Connecting to existing commandBar controls)
- Add Keyboard Shortcut – allows creating and intercepting application-level keyboard shortcuts
(see Intercepting keyboard shortcuts)
- Add Outlook Bar Shortcut Manager – allows adding Outlook Bar shortcuts and shortcut groups
(see Outlook Bar Shortcut Manager)
- Add Ribbon Tab – allows creating a custom Ribbon tab or modifying an existing (or built-in) Ribbon tab of the host application
(see Ribbon UI)
- Add Ribbon Command – allows re-purposing Ribbon controls
- Add Ribbon Quick Access Toolbar – allows customizing the Ribbon Quick Access Toolbar
- Add Ribbon Office Menu – allows customizing the Ribbon Office Menu
- Add Excel Task Panes Manager – see Advanced Excel task panes
- Add Outlook Forms Manager – see Advanced Outlook view and form regions – basic concepts
- Add Events – allows accessing application-level events of the host application (see Application-level events)
- Host configuration – see Conflicts with Office extensions
developed in .NET Framework 1.1
Releasing COM objects
When working with COM objects, remember these two rules:
- You must never release COM objects obtained through the parameters of events provided by Add-in Express.
- You must always release COM objects retrieved by you ("manually") from any COM object.
To understand why (and how) to release COM objects, consider the following code line:
C#:
Outlook.Explorer explorer = OutlookApp.ActiveExplorer();
VB.NET:
Dim explorer as Outlook.Explorer = OutlookApp.ActiveExplorer()
That code line creates three objects: a COM object corresponding to the active Outlook.Explorer and two .NET objects. The .NET objects are:
- A Runtime-callable wrapper (RCW) that references the COM object
- A .NET object that references the RCW. This .NET object is identified in your code as explorer.
When you set explorer to null (Nothing in VB.NET), the corresponding .NET object lives until the next run of the Garbage Collector (GC).
Accordingly, the RCW lives, too. And this means the COM object isn't released. The further course of events depends on the COM object you
created and the implementation of the COM server (it's Outlook in this example). Say, not releasing the COM object used in this example makes
Outlook 2000 – 2002 hang in processes and produces a delay in Outlook 2003-2007 when you close Outlook.
To release the COM object above, you need to use the Marshal.ReleaseComObject method (System.Runtime.InteropServices namespace) as follows:
C#:
if (explorer != null) Marshal.ReleaseComObject(explorer);
VB.NET:
If explorer IsNot Nothing Then Marshal.ReleaseComObject(explorer)
An extensive review of typical problems related to releasing COM objects in Office add-ins is given in an article published on the
our technical blog – When to release COM objects
in Office add-ins?. You may also want to read the following article - Why Outlook
is not closing when I run my add-in?
What is ProgId?
ProgID – Program Identifier. This is a textual name that represents a server object. It consists of the project name and the class name,
like MyServer.MyClass. You find it in ProgIDAttribute of an ADX Module. For instance:
...
'Add-in Express Add-in Module
<GuidAttribute("43F48D82-7C6F-4705-96BB-03859E881E2C"), _
ProgIdAttribute("MyAddin1.AddinModule")> _
Public Class AddinModule
Inherits AddinExpress.MSO.ADXAddinModule
...
Your Office COM add-in in the registry
Depending on the value of the RegisterForAllUsers property of the add-in module, the main registry entry of a COM add-in is located in:
If the RegisterForAllUsers property of the add-in module is true, the add-in is registered in HKE
{HKLM or HKCU}\Software\Microsoft\Office\{host application}\AddIns\{Add-in ProgID}
Y_LOCAL_MACHINE, otherwise the key is located in HKEY_CURRENT_USER. Pay attention to the LoadBehavior value defined in this key: typically it's 3;
if it's 2, this may be an indication of an unhandled exception at add-in startup. The registry key above notifies the corresponding Office application
that there's an add-in to load. JFYI, the COM add-in is a COM object registered in
HKEY_CLASSES_ROOT\CLSID\{Add-in Express Project GUID}
FolderPath Property Value is missing in Outlook 2000 and 2002 (XP)
This property is available in Outlook 2003, 2007 and Outlook 2010. For Outlook 2000 and 2002 (XP), use the following function to get a
full folder path for a folder:
Public Shared Function GetFolderPath(ByVal MAPIFolder As _
Outlook.MAPIFolder) As String
If MAPIFolder Is Nothing Then Return ""
Dim CurrentPath As String = ""
Do
CurrentPath = "\" + MAPIFolder.Name + CurrentPath
Dim Obj As Object = MAPIFolder.Parent
'The parent of a root folder is of the Outlook.Namespace type
If Not TypeOf Obj Is Outlook.MAPIFolder Then Exit Do
MAPIFolder = CType(Obj, Outlook.MAPIFolder)
Loop
CurrentPath = "\" + CurrentPath
Return CurrentPath
End Function
My COM add-in is always disconnected
If your add-in fires exceptions at startup, the host application (or the end-user) may block the add-in. Such add-ins fall into the Disabled Items list.
To find the list, in the host application, go to "Help", then "About". At the bottom of the About dialog, there is the Disabled Items button. Check it to see
if the add-in is listed there (if so, select it and click Enable). In the Ribbon UI of Office 2007, you find that list on the Add-ins tab of the Office Menu |
{host application} Options dialog.
How to develop the modular architecture of your COM add-in
Let's suppose that your COM add-in should conditionally provide (or not provide) some feature: let's call it MyFeature. You could create a class
library project, add an ADXAddinAdditionalModule (see Add New Item dialog), and implement the feature.
Then you create a setup project that could, at your choice, either register the assembly using the vsdrpCOM option in the Register
parameter of the assembly, or create appropriate keys in HKCU. Note that the former way may require the administrative privileges for the user.
Now the class library can write the ProgID of the ADXAddinAdditionalModule into the app.config file of the add-in. When the add-in starts,
it can read the app.config, create an ADXAddinAdditionalModuleItem and add it to the Modules collection of the ADXAddinModule class. The best
place is the AddinInitialize event of the add-in module. For instance:
Friend WithEvents FeatureA As _
AddinExpress.MSO.ADXAddinAdditionalModuleItem
Private Sub AddinModule_AddinInitialize( _
ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.AddinInitialize
Dim FeatureAProgId As String = System.Configuration. _
ConfigurationManager.AppSettings("FeatureAProgId")
If FeatureAProgId IsNot Nothing Then
Me.FeatureA = _
New AddinExpress.MSO.ADXAddinAdditionalModuleItem(Me.components)
Me.FeatureA.ModuleProgID = FeatureAProgId
Me.Modules.Add(Me.FeatureA)
End If
End Sub
If your ADXAddinAdditionalModule contains Ribbon controls, you will need to use the OnRibbonBeforeCreate event of the add-in module.
The same approach is applicable for the Excel XLL add-in. Just use proper
class types in the sample above.
Word add-ins, command bars, and normal.dot
Word saves changes in the UI to normal.dot: move a toolbar to some other location and its position will be saved to normal.dot when Word quits. The
same applies to add-ins: their command bars are saved to this file. See some typical support cases related to Word add-ins and normal.dot below.
- For reasons of their own, some organizations use read-only normal.dots. In this case, installing the add-in raises a warning, when Word tries to save
normal.dot and finds that it is read-only.
- The user can set the Prompt to Save Normal Template flag located on the Save tab in the Tools | Options menu and in this way decide whether to save
normal.dot or not. This may lead to a mess: some command bars and controls are saved while others are not.
- Other companies store lots of things in their normal.dot files making them too big in size; saving such files requires extra time.
- We have had scenarios in which normal.dot is moved or deleted after the add-in is installed; naturally, command bars disappear as well.
You may think that using temporary command bars in these cases is a way out, but this may not be your case, see
Commandbar and controls - temporary or not. We know the only workaround: don't use normal.dot in a way,
which wasn't designed by Microsoft. Normal.dot is a per-user thing. Don't deprive the user of the ability to change its UI. Move all excessive things to other
templates. Always insist on clearing the Prompt to Save Normal Template flag. If it is possible, of course...
Accessing public members of your COM add-in from another add-in or application
You can always access a public property or method defined in the add-in module via the following path:
HostApp.COMAddins.Item({the ProgID of your add-in}).Object.MyPublicPropertyOrMethod(MyParameter)
The ProgID value above can be found in the ProgID attribute of the add-in module. Note that you access the MyPublicPropertyOrMethod above
through late binding - see System.Type.InvokeMember. You can also find a number of samples in this document. And you can search our
forums for more samples. See also What is ProgID?
Custom actions when your COM add-in is uninstalled
When the add-in is being unregistered, the BeforeUninstallControls and AfterUninstallControls events occur. You can use them for,
say, removing “hanging” command bars from Word or restoring any other state that should be restored when your add-in is uninstalled.
XP Styles in your forms
Just call System.Windows.Forms.Application.EnableVisualStyles() in your add-in module, say in the AddinInitialize event.
Note that you access the MyPublicPropertyOrMethod above through late binding - see System.Type.InvokeMember.
Note. If you didn't find the answer to your questions on this page, please see the
HOWTOs section:
Back to Add-in Express for Office and .NET homepage |