Outlook’s slow add-ins resiliency logic and how to always enable slow add-ins


Overview

This post explains how to deploy registry settings that would force Outlook to always load a specific add-in.

The information in this post only applies to slow (VSTO) add-ins. If Outlook disables your add-in to prevent a crash, this blog post isn't for you.

Requirements

Outlook 2013 or 2016.

Information

Outlook 2013 and 2016's resiliency logic is triggered when one of the criteria enumerated in the Performance criteria for keeping add-ins enabled section of the New in Outlook for developers MSDN article.

Outlook's resiliency logic was introduced with Outlook 2013 and it builds on the foundation set by the resiliency logic in Outlook 2010. As opposed to 2010, Outlook 2013 allows controlling how slow add-ins are handled, giving the users the option to go with the default logic and disable add-ins that take longer than 1 second to load or unload for example, or choose to always enable a certain add-in.

This logic only applies to VSTO add-ins, it doesn't touch COM add-ins. This is why you'll see that add-ins such as the Microsoft Exchange add-in or the Skype for Business add-in are never disabled. Only VSTO add-ins are touched.

One other aspect to note is that if a VSTO add-in requires a module that is not loaded in Outlook's memory, the first add-in to require that module will incur a "penalty" for each additional module that is loaded. This will apply for all add-ins if a required module is not present, the load time of each module that is required will be added to the load time of the add-in.

In addition to modules, the first add-in to load will incur a penalty for loading the .Net Framework.

In conclusion:

  1. The first add-in to be loaded will have a load time equal to: LOAD_NECESSARY_MODULES + LOAD_.NET_FRAMEWORK + RUN_ADDIN_STARTUP_CODE
  2. All future add-ins to be loaded will have a load time equal to: LOAD_NECESSARY_MODULES + RUN_ADDIN_STARTUP_CODE.

Solution / Workaround

To work around the resiliency logic, one can use a simple .reg file and add the add-in to the trusted addins list or a Group Policy Object to deploy the same values that would be generated locally to all the users in the domain:

  1. Add a dword entry called ADDIN_NAME with a value data of 1 under HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Office\1x.0\Outlook\Resiliency\AddinList
  2. Set the LoadBehavior (US English spelling!) dword value to 3 under HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\Outlook\Addins\ADDIN_NAME
  3. Delete the HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\1x.0\Outlook\Resiliency\DisabledItems key
  4. Re-create the HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\1x.0\Outlook\Resiliency\DisabledItems key
  5. Delete the HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\1x.0\Outlook\Resiliency\CrashingAddinList key
  6. Re-create the HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\1x.0\Outlook\Resiliency\CrashingAddinList key
  7. Add a dword entry called ADDIN_NAME with a value of 1 under HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\1x.0\Outlook\Resiliency\DoNotDisableAddinList


Where:

  • ADDIN_NAME is the name of the add-in as found under HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\Outlook\Addins\
  • 1x.0 is the office version, for example 15.0 for Office 2013 and 16.0 for Office 2016

Here is a REG file example:

Windows Registry Editor Version 5.00
 
[HKEY_CURRENT_USER\Software\Policies\Microsoft\Office\1x.0\Outlook\Resiliency\AddinList]
 "ADDIN_NAME"=dword:00000001
[HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\Outlook\Addins\ADDIN_NAME]
 "LoadBehavior"=dword:00000003
[-HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\1x.0\Outlook\Resiliency\DisabledItems]
[HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\1x.0\Outlook\Resiliency\DisabledItems]
[-HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\1x.0\Outlook\Resiliency\CrashingAddinList]
[HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\1x.0\Outlook\Resiliency\CrashingAddinList]
[HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\1x.0\Outlook\Resiliency\DoNotDisableAddinList]
 "ADDIN_NAME"=dword:00000001

As far as group policy objects go, please find below the procedure:

  1. Open the Group Policy Management console on a domain controller
  2. Navigate to the domain node, right click it and select Create a GPO in this domain, and Link it here
  3. Give the GPO the desired name
  4. Right click the newly created GPO and click on Edit
  5. In the Group Policy Management Editor, expand Preferences under User Configuration
  6. Afterwards expand Windows Settings
  7. Right click Registry and create the following 7 entries:
Name
​Order
​Action
​Hive
​Key
​Value Name
​Type
​Value Data
ADDIN_NAME​
1​
Create ​
HKEY_CURRENT_USER ​
SOFTWARE\Policies\Microsoft\Office\1x.0\Outlook\Resiliency\AddinList​
ADDIN_NAME ​
REG_DWORD ​
00000001​​
LoadBehavior ​
2​
Update
HKEY_CURRENT_USER ​
SOFTWARE\Microsoft\Office\Outlook\Addins\ADDIN_NAME​
LoadBehavior ​
REG_DWORD ​
00000003​​
DisabledItems ​
3​
Delete ​
HKEY_CURRENT_USER ​
SOFTWARE\Microsoft\Office\1x.0\Outlook\Resiliency\DisabledItems​
DisabledItems ​
4​
Create ​
HKEY_CURRENT_USER ​
SOFTWARE\Microsoft\Office\1x.0\Outlook\Resiliency\DisabledItems​
CrashingAddinList​
5
Delete ​
HKEY_CURRENT_USER ​
SOFTWARE\Microsoft\Office\1x.0\Outlook\Resiliency\CrashingAddinList ​
CrashingAddinList​
6​
Create ​
HKEY_CURRENT_USER ​
SOFTWARE\Microsoft\Office\1x.0\Outlook\Resiliency\CrashingAddinList ​
ADDIN_NAME ​
7​
Create ​
HKEY_CURRENT_USER ​
SOFTWARE\Microsoft\Office\1x.0\Outlook\Resiliency\DoNotDisableAddinList​
ADDIN

 

Please find below a PowerShell script sample that sets the above registry settings. Please save the script block as Enable-AddIn.ps1.

The syntax to run the script is Enable-AddIn.ps1 -AddinName ADDIN_NAME, where add-in name is the name of the add-in to always enable. The script will run once and set a registry value as a checkpoint. To force it to run again you can use the -Force parameter.

For example:

  • Enable-AddIn.ps1 -AddinName MyAddIn to run the script once and always enable MyAddIn
  • Enable-AddIn.ps1 -AddinName MyAddIn -Force to always run the script and enable MyAddIn

For more information on how to configure a script via GPO, please check the following article: https://technet.microsoft.com/en-us/library/cc770908(v=ws.11).aspx

param(
[Parameter(Mandatory=$true)]
[string]$AddinName,
[Parameter(Mandatory=$false)]
[switch]$Force
)

$AddinList = $null
$CrashingAddinList = $null
$DoNotDisableAddinList = $null

function Get-Key
(
[string]$ParentKey,
[string]$KeyName)
{
    for ($i = 0; $i -lt $KeyName.Split("\").Count; $i++)
    {
        try
        {
            $Key = get-item -Path ("{0}:\{1}" -f $ParentKey,($KeyName.split("\")[0..$i] -join "\"))
        }
        catch 
        {
            $Key = new-item -Path ("{0}:\{1}" -f $ParentKey,($KeyName.split("\")[0..$i] -join "\"))
        }
    }
    return $Key
}

$ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
$OutlookVersion = (Get-ItemProperty HKLM:\SOFTWARE\Classes\Outlook.Application\CurVer)."(default)".Replace("Outlook.Application.", "")

if ($Force)
{
    $checkPoint = $null
}
else
{
    try
    {
        $CheckPoint = (Get-Item "HKCU:\Software\Microsoft\Office\$OutlookVersion.0\Outlook\Resiliency" | Get-ItemProperty)."CheckPoint" -eq 1
    }
    catch
    {
        $checkPoint = $false
    }
}

if (-not $checkPoint)
{
    Get-Key -ParentKey HKCU -KeyName "Software\Policies\Microsoft\Office\$OutlookVersion.0\Outlook\Resiliency\AddinList" | Set-ItemProperty -Name $AddinName -Value 1
    Get-Key -ParentKey HKCU -KeyName "Software\Microsoft\Office\$OutlookVersion.0\Outlook\Resiliency\DoNotDisableAddinList" | Set-ItemProperty -Name $AddinName -Value 1
    Get-Key -ParentKey HKCU -KeyName "Software\Microsoft\Office\$OutlookVersion.0\Outlook\Resiliency\DisabledItems" | Remove-Item
    Get-Key -ParentKey HKCU -KeyName "Software\Microsoft\Office\$OutlookVersion.0\Outlook\Resiliency\DisabledItems" | Out-Null
    Get-Key -ParentKey HKCU -KeyName "Software\Microsoft\Office\$OutlookVersion.0\Outlook\Resiliency\CrashingAddinList" | Remove-Item
    Get-Key -ParentKey HKCU -KeyName "Software\Microsoft\Office\$OutlookVersion.0\Outlook\Resiliency\CrashingAddinList" | Out-Null
    Get-Item "HKCU:\Software\Microsoft\Office\$OutlookVersion.0\Outlook\Resiliency" | Set-ItemProperty -Name "CheckPoint" -Value 1
}


Revisions

Original version: 2017-08-02
Update: 2017-10-31  - corrected the registry entries.
Update: 2017-11-27  - added additional entries to account for crashing add-ins.
Comments (7)

  1. Nick Botica says:

    Will this require the user to close and open Outlook?
    What if I setup GPO to delete the SOFTWARE\Microsoft\Office\1x.0\Outlook\AddInLoadTimes ADDIN_NAME value.
    And delete the SOFTWARE\Microsoft\Office\1x.0\Outlook\Addins\ADDIN_NAME key.

    Then Outlook won’t get 5 start time readings and have any reason to disable it?

    What does “Software\Policies\Microsoft\Office\1x.0\Outlook\Resiliency\AddinList​” do exactly? Will this stop Outlook disabling the addin no matter what (well due to loading times anyway)?

  2. Nick Botica says:

    In the table at the bottom the Key path doesn’t have the Outlook version. Should it? All your other examples do.

    1. Andrei Ghita says:

      You are correct, ti should include the Office version key.

  3. Jarrod says:

    I believe ADDIN_NAME should be a String (REG_SZ) value “1” instead of a DWORD as follows?

    [HKEY_CURRENT_USER\Software\Policies\Microsoft\Office\1x.0\Outlook\Resiliency\AddinList]
    “ADDIN_NAME”=”1”

    1. Andrei Ghita says:

      Hmmm, not according to MSDN (https://msdn.microsoft.com/en-us/vba/outlook-vba/articles/support-for-keeping-add-ins-enabled) but I’ll double check and update the post if needed.

  4. Eric Shao says:

    Hi Andrei, “If Outlook disables your add-in to prevent a crash, this blog post isn’t for you.” Do you have another post to deal with this kind of situation? Is it possible to prevent Outlook from disabling my add-in which causes outlook to crash?

    1. Andrei Ghita says:

      Hi Eric,

      Have a look at the “Troubleshooting Startup Errors by Using a Log File and Error Messages” section in https://msdn.microsoft.com/en-us/library/ms269003.aspx and set VSTO_SUPPRESSDISPLAYALERTS to 0 to allow for a pop-up that displays information on any exceptions that might occur at load time.

      If you do get a pop-up, be sure to click on details, copy the exception details and get back to me with the details.

      There isn’t a guide on troubleshooting crashing add-ins. Unless there’s an obvious reason for the crash, we usually end up debugging Outlook and the add-in to understand why it crashes.

      Andrei

Skip to main content