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 in Outlook 2013 or higher.  If Outlook disables your add-in to prevent a crash, this blog post isn't for you.

EDIT: This logic now applies to all COM and VSTO add-ins.

Disclaimer

Outlook natively allows add-ins to be enabled one at a time. That's the only official supported way to enable slow add-ins!

This blog post is a best effort to allow users to automate the process at a large scale. This doesn't mean Microsoft CSS is obligated in any way to support this, it's simply a best effort.

Requirements

Outlook 2013 or 2016.

How it works

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.

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 ] [+ LOAD_VSTO_RUNTIME] + 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.

IMPORTANT: Outlook's resiliency logic thresholds are hard coded. For example, the startup time is set to 1000 milliseconds (1 second). This limit cannot be increased, but by following the instructions in this blog post you can tell Outlook to load the add-in despite a load time of more than 1 second. 

Detailed Steps

REGISTRY

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
  8. Add a dword entry called ADDIN_NAME\dtype with a value of 0 under HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\1x.0\Outlook\Resiliency\NotificationReminderAddinData
  9. Add a dword entry called ADDIN_NAME with a value of 967a844d hexadecimal or 2524611661 decimal under HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\1x.0\Outlook\Resiliency\NotificationReminderAddinData

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

NOTE: The value at point 1 will always enable the add-in but it will also prevent the user from controlling the add-in load behaviour. To allow users to control the add-in (enable or disable it from the Outlook user interface), set a value data of 2 (or dword:00000002 for the reg file) instead.  

NOTE: The value at point 9 always enables your add-in until Saturday, January 1st 2050 at 1:01:01 AM.

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
[HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\1x.0\Outlook\Resiliency\NotificationReminderAddinData] 
"ADDIN_NAME\dtype"=dword:00000000
[HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\1x.0\Outlook\Resiliency\NotificationReminderAddinData] 
"ADDIN_NAME"=dword:967a844d 

GPO (Group Policy Object)

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 9 entries:
Name
​Order​
Action​
Hive​
Key​Value
Name​
Type
​ValueData
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_NAME
​REG_DWORD
​00000001​​
​ADDIN_NAME
​8
Create
​HKEY_CURRENT_USER
​SOFTWARE\Microsoft\Office\1x.0\Outlook\Resiliency\NotificationReminderAddinData​
ADDIN_NAME\dtype
REG_DWORD
​00000000
ADDIN_NAME
​9
Create
​HKEY_CURRENT_USER
​SOFTWARE\Microsoft\Office\1x.0\Outlook\Resiliency\NotificationReminderAddinData
​ADDIN_NAME
REG_DWORD
967a844d

POWERSHELL SCRIPT

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: Assign User Logon Scripts

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-Key -ParentKey HKCU -KeyName "Software\Microsoft\Office\$OutlookVersion.0\Outlook\Resiliency\NotificationReminderAddinData" | Set-ItemProperty -Name ([string]::Format("{0}\dtype",$AddinName)) -Value 2
     Get-Key -ParentKey HKCU -KeyName "Software\Microsoft\Office\$OutlookVersion.0\Outlook\Resiliency\NotificationReminderAddinData" | Set-ItemProperty -Name $AddinName -Value 2524611661
     Get-Item "HKCU:\Software\Microsoft\Office\$OutlookVersion.0\Outlook\Resiliency" | Set-ItemProperty -Name "CheckPoint" -Value 1
}

NOTE: To allow users to control the add-in (enable or disable it from the Outlook user interface), replace "-value 1" with "-value 2" in the following script line: Get-Key -ParentKey HKCU -KeyName "Software\Policies\Microsoft\Office\$OutlookVersion.0\Outlook\Resiliency\AddinList" | Set-ItemProperty -Name $AddinName -Value 1

Notes

Please follow the instructions carefully and for best results use the PowerShell script above.

References

New in Outlook for developers

Assign User Logon Scripts

Assign User Logon Scripts

Change Log

Date Author Type Description
02/08/2017 Andrei Ghita Original
31/10/2017 Andrei Ghita Update Corrected the registry entries.
27/11/2017 Andrei Ghita Update Added additional entries to account for crashing add-ins.
10/12/2018 Natercia Gomes Update Added additional entries for Outlook 2016.
16/01/2019 Andrei Ghita Update Updated general info to include COM add-ins and explained the reg value that controls the time the add-in stays enabled.
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”

  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