0

Problem Summary

I have a critical issue with my SDK-Style generated VSTO Outlook add-in when deployed via WiX MSI installer. The same VSTO files work perfectly when installed directly (double-click .vsto file) but fail when packaged in an MSI installer.
The same VSTO generated via OldStyle CSProj packed into an MSI installs and works perfectly.

TL-DR: Solution is in this question below,
thanks to @lauxjpn, @Nikolay and @Dmitry Streblechenko

This question builds upon: VSTO Outlook Add-in SDK-style project fails to generate vsto and dll manifest

Environment

  • Project Type: SDK-style .csproj with VSTO
  • Target Framework: .NET Framework 4.7.2
  • Office Version: Outlook 2016/2019/365
  • WiX Version: 3.14
  • Build System: MSBuild 17.14
  • OS: Windows 11 (64-bit)

Working vs Non-Working Scenarios

WORKING: Direct VSTO Installation

Installed directly using double-click on the .vsto file, or:

# This works perfectly
VSTOInstaller.exe /install "path\to\Minimal.BIEM.Outlook.vsto" /silent
  • Installs to HKCU (per-user)
  • Outlook loads add-in successfully
  • All functionality works as expected

NOT WORKING: MSI Installation

My WiX build process takes exactly the same VSTO files and packs them into an MSI. Then:

# MSI installs without errors, but add-in won't load
msiexec /i "Minimal.BIEM32Setup.msi" /quiet
  • MSI installation completes successfully
  • All files copied to the ususal Program Files destination correctly
  • Registry entries created in HKLM as usual
  • Outlook Error: "Not loaded. A runtime error occurred during the loading of the COM add-in."
    Or in german: "Nicht geladen. Während des Ladens des COM-Add-Ins ist ein Laufzeitfehler aufgetreten."

Project Structure

BIEM-SdkStyle.csproj and BIEM-OldStyle.csproj

see here: VSTO Outlook Add-in SDK-style project fails to generate vsto and dll manifest

WiX Project SetupBIEM.wixproj

<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
    <ProductVersion>3.7</ProductVersion>
    <ProjectGuid>{4a8159fb-f544-489b-9b6f-c6b048b929df}</ProjectGuid>
    <SchemaVersion>2.0</SchemaVersion>
    <OutputName>Minimal.BIEM32Setup</OutputName>
    <OutputType>Package</OutputType>
    <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
    <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
    <!-- Override WixTargetsPath if the default locations don't exist (e.g., when using VS Build Tools) -->
    <WixTargetsPath Condition=" '$(WixTargetsPath)' != '' AND !Exists('$(WixTargetsPath)') ">C:\Program Files (x86)\MSBuild\Microsoft\WiX\v3.x\wix.targets</WixTargetsPath>
    <Name>SetupBIEM</Name>
    <SuppressValidation>true</SuppressValidation>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
    <OutputPath>bin\$(Configuration)\</OutputPath>
    <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
    <DefineConstants>Debug</DefineConstants>
    <SuppressAllWarnings>False</SuppressAllWarnings>
    <Pedantic>True</Pedantic>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
    <OutputPath>bin\$(Configuration)\</OutputPath>
    <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="Product.wxs" />
    <Content Include="config\postbuild.xml" />
    <Content Include="IncludeBiem.wxi" />
    <Folder Include="config" />
  </ItemGroup>
  <Import Project="$(WixTargetsPath)" />
</Project>

WiX Configuration (Product.wxs)

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Product Id="*" UpgradeCode="..." Name="MyCompany BIEM 3.2" 
           Manufacturer="MyCompany" Language="1031" Version="3.2.2">
    
    <Package InstallerVersion="300" Compressed="yes" InstallScope="perMachine" />
    
    <Feature Id="AddInBIEM" Title="Setup BIEM" Level="1">
      <ComponentRef Id="AddInBiem" />
    </Feature>

    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="MyCompany" Name="MyCompany">
          <Directory Id="INSTALLLOCATION" Name="BIEM">
            <Component Id="AddInBiem" Guid="..." KeyPath="yes">
              
              <!-- VSTO Files -->
              <File Source="$(var.ProjectDir)..\Installation\FilesForMSI\Minimal.BIEM.Outlook.dll" />
              <File Source="$(var.ProjectDir)..\Installation\FilesForMSI\Minimal.BIEM.Outlook.dll.config" />
              <File Source="$(var.ProjectDir)..\Installation\FilesForMSI\Minimal.BIEM.Outlook.dll.manifest" />
              <File Source="$(var.ProjectDir)..\Installation\FilesForMSI\Minimal.BIEM.Outlook.vsto" />
              
              <!-- MS Office Tools DLLs -->
              <File Source="$(var.ProjectDir)..\Installation\FilesForMSI\Microsoft.Office.Tools.*.dll"/>
              
              <!-- Outlook Add-in Registration -->
              <RegistryKey Root="HKLM" Key="Software\WOW6432Node\Microsoft\Office\Outlook\Addins\Minimal.BIEM.Outlook">
                <RegistryValue Name="Description" Value="Versenden von E-Mails nach Extern aus Outlook" Type="string"/>
                <RegistryValue Name="FriendlyName" Value="MyCompany BIEM 3.2" Type="string"/>
                <RegistryValue Name="Manifest" Value="C:\Program Files (x86)\MyCompany\BIEM\Minimal.BIEM.Outlook.vsto|vstolocal" Type="string"/>
                <RegistryValue Name="LoadBehavior" Value="3" Type="integer"/>
              </RegistryKey>
              
            </Component>
          </Directory>
        </Directory>
      </Directory>
    </Directory>
  </Product>
</Wix>

Troubleshooting Attempts

1. Registry Analysis

I thoroughly cleaned up all registry entries between all tries (HKCU & HKLM), but the problem remaines reproducible:

  • SDK-Style generated VSTO add-ins fail, when installed via MSI (HKLM registry), but works perfectly when installed via double-click (HKCU registry).
  • The BIEM-OldStyle.csproj generated VSTO packed into an MSI installs and works perfectly.

Working VSTO Installation (HKCU):

HKCU\SOFTWARE\Microsoft\Office\Outlook\Addins\Minimal.BIEM.Outlook
├── Description: "Versenden von E-Mails nach Extern aus Outlook"
├── FriendlyName: "MyCompany BIEM 3.2"
├── Manifest: "file:///C:/Work/.../Minimal.BIEM.Outlook.vsto|vstolocal"
└── LoadBehavior: 3

MSI Installation (HKLM):

HKLM\SOFTWARE\WOW6432Node\Microsoft\Office\Outlook\Addins\Minimal.BIEM.Outlook
├── Description: "Versenden von E-Mails nach Extern aus Outlook"
├── FriendlyName: "MyCompany BIEM 3.2"
├── Manifest: "C:\Program Files (x86)\MyCompany\BIEM\Minimal.BIEM.Outlook.vsto|vstolocal"
└── LoadBehavior: 3

2. VSTO Security Trust Attempts

Tried adding VSTO security registry entries:

<RegistryKey Root="HKLM" Key="SOFTWARE\Microsoft\VSTO\Security\Inclusion\{guid}">
  <RegistryValue Name="Url" Value="file:///C:/Program Files (x86)/MyCompany/BIEM/Minimal.BIEM.Outlook.vsto" Type="string"/>
  <RegistryValue Name="PublicKey" Value="&lt;RSAKeyValue&gt;...&lt;/RSAKeyValue&gt;" Type="string"/>
</RegistryKey>

I have seen simmilar entries in HKCU\Software\Microsoft\VSTO after I installed the VSTO directly (double-click .vsto file).

3. File Verification

All files are identical between working and non-working installations, i.e. in my bin\Release and Program Files destination directory:

  • Minimal.BIEM.Outlook.dll (same size, same timestamp)
  • Minimal.BIEM.Outlook.vsto (same content, same signature)
  • Minimal.BIEM.Outlook.dll.manifest (identical)
  • All Microsoft.Office.Tools.*.dll files present

4. Outlook Diagnostics

Event Viewer Analysis:

# Outlook successfully loads other add-ins but not BIEM
Get-WinEvent -FilterHashtable @{LogName='Application'; Id=45} | 
  Where-Object {$_.Message -like "*Outlook loaded*"}

Shows working add-ins but BIEM is completely missing from the list and there were no other messages, why my add-in was not loaded.

5. MSI Installation Logs

MSI (s) (8C:30) [19:55:14:845]: Product: MyCompany BIEM 3.2 -- Installation completed successfully.
  • MSI installation reports success
  • All files copied correctly
  • Registry entries created as expected
  • No error messages in MSI log

Comparison: Old-Style vs SDK-Style

Working Solution with BIEM-OldStyle.csproj

The same MSI installer works perfectly with old-style project:

<!-- Old-style project file that works with MSI -->
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectTypeGuids>{BAA0C2D2-18E2-41B9-852F-F413020CAA33};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
    <!-- ... standard VSTO properties ... -->
  </PropertyGroup>
  <!-- ... rest of old-style configuration ... -->
</Project>

This suggests the issue is specifically related to SDK-style project output compatibility with MSI deployment.

Current Workaround

Due to this critical issue, I was forced to maintain two project files:

  1. BIEM-SdkStyle.csproj - For modern .NET builds and CI/CD
  2. BIEM-OldStyle.csproj - For VSTO generation and MSI packaging

This is "suboptimal".

Questions

  1. What causes SDK-style VSTO projects to fail when deployed via MSI but work with direct installation?

  2. Are there specific MSBuild properties or VSTO targets that need to be configured differently for SDK-style projects to work with MSI deployment?

  3. Is there a difference in the generated VSTO manifest or assembly metadata between old-style and SDK-style projects that affects MSI deployment?

  4. What's the recommended approach for deploying SDK-style VSTO projects machine-wide (HKLM) instead of per-user (HKCU)?

  5. How to see some Outlook logs, which can say what's not satisfied or causing an error?

Additional Information

  • VSTO Runtime: Microsoft Visual Studio 2010 Tools for Office Runtime installed
  • Office Installation: Click-to-Run Microsoft 365
  • Code Signing: Assembly is properly signed with company certificate
  • Trust Settings: No ClickOnce trust issues (works with direct install)

Any insights into why SDK-style VSTO projects behave differently in MSI deployments would be greatly appreciated!


Edit / Solution

Thanks to guidance from @lauxjpn, @Nikolay and @Dmitry Streblechenko (see their answers and comments below), I was able to resolve this issue.
The key takeaways were:

  1. The solution was to examine, what additional files are necessary to install the VSTO locally using double-click = Direct VSTO Installation in HKCU. I tried until it worked.
    After I estimated all necessary files, I closed Outlook and uninstalled the VSTO, leaving all necessary files still in place. So I only checked my registry to be clean after the uninstall.
  2. Then I checked I have 64bit Win 11, but 32bit Outlook, and my VSTO is AnyCPU, so I used the WOW6432Node registry for my case (for more see the answer of @lauxjpn below).
    I used HKLM instead of HKCU, and following registry entry worked for me immediately:
HKLM\SOFTWARE\WOW6432Node\Microsoft\Office\Outlook\Addins\Minimal.BIEM.Outlook
├── Description: "Versenden von E-Mails nach Extern aus Outlook"
├── FriendlyName: "MyCompany BIEM 3.2"
├── Manifest: "file:///C:/Program Files (x86)/MyCompany/BIEM/Minimal.BIEM.Outlook.vsto|vstolocal"
└── LoadBehavior: 3

The DLLs I was missing prior to the fix were 4 System.*.dll-s from my bin compile directory - here the full list of all necessary files for my case:

Minimal.BIEM.Outlook.dll
Minimal.BIEM.Outlook.dll.config
Minimal.BIEM.Outlook.dll.manifest
Minimal.BIEM.Outlook.vsto
Microsoft.Office.Tools.Common.dll
Microsoft.Office.Tools.Common.v4.0.Utilities.dll
Microsoft.Office.Tools.dll
Microsoft.Office.Tools.Outlook.dll
Microsoft.Office.Tools.Outlook.v4.0.Utilities.dll
Microsoft.Office.Tools.v4.0.Framework.dll
Microsoft.VisualStudio.Tools.Applications.Runtime.dll
System.Memory.dll
System.Numerics.Vectors.dll
System.Resources.Extensions.dll
System.Runtime.CompilerServices.Unsafe.dll

My original problem was, for the case of file:///C:/Program Files (x86)/... I always forgot to add the |vstolocal at the end of the entry in my tests. I did tons of frustrating tests and was wrong until this small changes. Even AI was no help in my case. So thank you guys: @lauxjpn, @Nikolay and @Dmitry Streblechenko for your very good hints!

3
  • 1
    Does including file:/// for HKLM make any difference? Commented Sep 5 at 16:51
  • @DmitryStreblechenko If it resets LoadBehavior from 1 to 3, that means it sees the addin, tries to load it, but fails (typically, caused by a missing dependency/dll). So the URL is hardly an issue here. Commented Sep 7 at 11:28
  • @Dmitry Streblechenko: I tested: "file:///C:/Program Files (x86)/..." and "file:///C:/Program%20Files%20(x86)/..." and both didn’t work for my SDK-Style generated VSTO, but the 2nd of them brought 1-time message (i.e. not reproducible): System.ArgumentException: Application identity does not match identities in manifests. at Microsoft.VisualStudio.Tools.Applications.Deployment.ClickOnceAddInDeploymentManager.GetManifests(TimeSpan timeout) at Microsoft.Vis...mentManager.InstallAddIn() Funny, that in HKCU via double click it does not have this problem Commented Sep 12 at 12:21

2 Answers 2

1

It appears that you are missing some necessary DLLs; this is a common pitfall. I mean, your MSI installer is just missing the DLL files required for your add-in to run. Look at the content of your "bin" folder after build (or what is installed with ClickOnce under local user profile) - do all files present? Can you actually see all of them in your app's folder in Program Files? Only copying the AddIn's DLL is mostly not enough. Wix, unlike ClickOnce, does not automatically include dependencies; you need to do it explicitly.

Sign up to request clarification or add additional context in comments.

4 Comments

I tried without success: manually copied all VSTO incl. all DLL and other files to my app's folder in Program Files dir and tried until it could install by double click and all works in Outlook. Then I exported all HKCU registry entries, uninstalled via VSTOInstaller and checked registry is clean. All files still in place. Then Added all HKLM entries as usual, even changed those exported from HKCU to HKLM - with and without WOW6432Node, but still have the problem. Please post here your working registry entries, or tell me if you need mine.
Have you tried to create the registry entries manually? I would try that first. In fact, when you build your add-in, Visual Studio creates these entries for you (so that you can debug the add-in). You can examine those and compare them to ones created with your setup.
yes, that's exactly, what I meant with my comment 2h ago. In a clean state I tried to copy all the VSTO, DLLs etc. files manually to the destination folder - to my app's folder in Program Files dir and tried double click it until it could install successfully. Then all worked in Outlook. After this I exported all relevant HKCU registry entries. Then I uninstalled it with VSTOInstaller, but left all the files in place in Program Files. At the End I tried several combinations of manual registry entries in HKLM, to simulate installation, but didn't get it run in Outlook. Still the same error.
The problem is only with the SDK-Style generated VSTO. The OldStyle CSProj packed into an MSI installs and works perfectly. The SDK-Style generated VSTO works only via double-click install (with entries just in HKCU).
1

(I am assuming your project compiles for Any CPU (the default).)

First test with a manual installation by copying the files to a target system and registering them by hand, e.g. via PowerShell:

# 64-Bit Office on 64-Bit Windows:
$keyPath = "HKCU:\Software\Microsoft\Office\Outlook\Addins\outlook-duplicate-remover"
# 32-Bit Office on 64-Bit Windows:
# $keyPath = "HKCU:\Software\Wow6432Node\Microsoft\Office\Outlook\Addins\outlook-duplicate-remover"

$key = (Get-Item $keyPath -ErrorAction SilentlyContinue) ?? (New-Item $keyPath)
$key | New-ItemProperty -Name 'FriendlyName' -PropertyType String -Value 'Outlook Duplicate Remover' -Force
$key | New-ItemProperty -Name 'Description' -PropertyType String -Value 'Removes duplicate emails from a selected folder.' -Force
$key | New-ItemProperty -Name 'Manifest' -PropertyType String -Value 'file:///C:/MyOutlookAddins/OutlookDuplicateRemover/outlook-duplicate-remover.vsto|vstolocal' -Force
$key | New-ItemProperty -Name 'LoadBehavior' -PropertyType DWord -Value 3 -Force # 2 = manually loadable after each startup, 3 = automatically load on each startup

(This is the code I am actively using to install one of my Outlook addins.)

Depending on the processor architecture and the Office build (x64/x86) the registry path changes. See Add-ins for Office programs may be registered under the \Wow6432Node for more information.

After you verified that your addin works by manually copying it and adding the correct registry keys, check that your setup copies all the necessary files and creates the exact same registry keys as well (with paths for the correct Windows bitness and Office bitness). The Manifest value should use the file:/// schema.

(Also, if you get the bitness of your project wrong (if not using Any CPU), you should find a corresponding error entry in the Application Windows Event Log when Outlook tries to load your addin).

1 Comment

Thank you much, your "stand by" with my Outlook Addin problems worked again like a charm! Despite your usage of HKCU, it worked for me in HKLM too. The solution to my problem was adding some missing System.*.dll-s and I was missing the the |vstolocal at the end of my HKLM Manifest. Necessary was the form: 'file:///C:/Program Files (x86)/My Company/MyPlugin/MyPlugin.vsto|vstolocal'. See my latest edit of my question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.