Andrei Smolin

How to load your Office COM add-in on condition

A typical problem is: how to unload my add-in if a custom condition is met. The condition can be a specific user ("Don't load the add-in for this and that users") or user's permissions, Office version, etc. This blog is about how to solve this problem.

The host application e.g. Outlook or Excel loads your add-in if it is properly registered and if LoadBehavior is set to 3 in the registry. The exact registry branch depends on your add-in type:

  • for a per-user add-in it is HKEY_CURRENT_USER\Software\Microsoft\Office\{host application}\Addins\{your add-in ProgId}
  • for a per machine it is HKEY_LOCAL_MACHINE\Software\Microsoft\Office\{host application}\Addins\{your add-in ProgId}

This said, a way to prevent your add-in from loading is to set LoadBehavior = 0 in {HKLM and HKCU}\Software\Microsoft\Office\{host application}\Addins\{your add-in ProgId}. Naturally, modifying anything in HKLM requires administrative permissions and this means that a standard user cannot turn off a per-machine add-in. There's an exception however: Office 2010 allows a standard user to turn a per-machine add-in off by unchecking the add-in in the COM Add-ins dialog. This creates HKCU\Software\Microsoft\Office\{host application}\Addins\{your add-in ProgId} and puts LoadBehavior=2 there!

The above is applicable only before the host application starts loading the add-in. But after the host application starts loading the add-in, you cannot do anything to stop the process.

The correct way in this situation is to disable the UI as well as event handling in your add-in. That is, you move the focus from "add-in loading / unloading" to "add-in functioning or not functioning". This is demonstrated by the add-in project accompanying the article. The idea is to remove all components from the add-in module before Add-in Express processes the components to create the corresponding UI elements such as toolbars and Ribbons.

C#:

private void RemoveComponents()
{
    for (int i = this.components.Components.Count - 1; i >= 0; i--)
        this.components.Remove(this.components.Components[i]);
}

VB.NET:

Private Sub RemoveComponents()
    For i As Integer = Me.components.Components.Count - 1 To 0 Step -1
        Me.components.Remove(Me.components.Components(i))
    Next i
End Sub

The method above must be run in the very first event the add-in fires. There are two candidates: AddinInitialize and OnRibbonBeforeCreate. The former is always the first event your add-in receives when loaded by a non-Ribbonned Office application e.g. Excel 2000-2003; sometimes it occurs first in a Ribbonned application e.g. Excel 2007-2010. OnRibbonBeforeCreate usually occurs first in Ribbonned applications. Pay attention to these “always” and “usually”.

Theoretically, there are two more ways: a) to fire an exception in AddinInitialize and b) to find an Office.COMAddin object corresponding to your add-in in the Application.COMAddins collection of the host application and set COMAddin.Connect = false.

However, both smell. Throwing an exception will set LoadBehavior=2 and your add-in will never have a chance to decide whether to load or not. Setting COMAddin.Connect=false is somewhat better but doesn’t it resemble pulling yourself up by your own hair to escape from a swamp? I don't recommend going this route: it may work for you now and fire an exception for the customer.

In case the condition is "the user loading the add-in belongs (or does not belong) to some user group", just everything above isn't required if you install the add-in via Group Policy: an administrator may uninstall the add-in for such users. We describe installing using Group Policy in HowTo: Install a COM add-in automatically using Windows Server Group Policy. If you use Add-in Express, step-by-step instructions on preparing your add-in for installation via Group Policy are here.

Good luck!

Available downloads:

These sample COM Add-ins were developed using Add-in Express for Office and .net:

C# sample COM add-in
VB.NET sample COM add-in

2 Comments

  • Willi Wildhaber says:

    I have build a Outlook Addin (2007 and newer) witch contains a adxOIFormsManager and one ADXOIForm with FormCollectionItem Settings ExplorerLayout: BottomSubpane, ExporerItemTypes: olMailItem, InspectorItemTypes olMail. When i run the Addin the Form will displayed as expected.

    Now i try to stop the Addin Load Procedure by implementing the AddinModule_AddinInitialize Event as described in the Article:

    private void AddinModule_AddinInitialize(object sender, EventArgs e)
    {
    RemoveComponents();
    }

    private void RemoveComponents()
    {
    for (int i = this.components.Components.Count – 1; i >= 0; i–)
    this.components.Remove(this.components.Components[i]);
    }

    When i now Run the Addin, the Form ist still created even if the RemoveComponent() Method is called. When i debug step by step througth the RemoveComponents() Method called by AddinModule_AddinInitialize, i can see the removal of the two ComponentCollection Entries
    [0] [AddinExpress.OL.ADXOlFormsManager]
    [1] [AddinExpress.OL.ADXOlFormsCollectionItem]
    and at the End of the RemoveComponent() Method the ComponentCollection ist empty.

    Why does the above Method not work on ADXOlFormsManager / ADXOlFormsCollectionItem Elements and how can i remove a Outlook Forms Addin ?
    I use Addin Express Version 6.6.3059

    Thank you for your Answer

  • Andrei Smolin (Add-in Express Team) says:

    That was my fault after all. Sorry for this.

    You need to clear the Items collection of the manager in the ADXOlFormsManager.OnInitialize event:

    adxOlFormsManager1.Items.Clear();

    In other host applications, you deal with this in the same way, see ADXExcelTaskPanesManager.ADXInitialize, ADXWordTaskPanesManager.ADXInitialize and ADXPowerPointTaskPanesManager.ADXInitialize events.

    Thank you for pointing me to this!

Post a comment

Have any questions? Ask us right now!