I developed a VSTO
Word
add in
in VS 2017 Pro. Works fine, ready to deploy. However, I cannot find a working procedure for packaging my VSTO
Word
add in
for use on machines other than my development machine. For any particular machine , I need to deploy it once and have it available for any user who may login using their account.
First came across this, but it involves using InstallShield Limited Edition which, apparently is no longer available for VS 2017.
Tried this but it a few of its steps seem to be missing parts or say "do x" without explaining how.
Tried 'InnoSetup' and the 'bovendor/VstoAddinInstaller', but following the 'bovendor' procedure results in the 'Innosetup' compiler throwing an error (a bovender-dictated stanza is missing a required element). Can't get a response from bovendor.
Searched Microsoft
docs and just can't find a procedure. Can anyone provide the procedure for packaging a VSTO Word add in for deployment?
Update
Successfully packaged and deployed my add-in using the WiX tool set. See my answer below
Update (11/26/2019): If your setup uses 64-bit Office, see How do you package a VSTO Word addin for deployment to a 64-bit Windows 10 machine running Microsoft Office 64 bit using WIX?
Successfully packaged and deployed my add-in
using the WiX
tool set
Credit: I learned most of this using Pieter van der Westhuizen's example on the Add-in Express Blog.
I used Visual Studio Pro 2017
, .NET 4.6.1
, and C#
on my development machine (64-bit) to implement my VSTO
Word
add-in.
My requirement is to deploy the add-in
once to a 64-bit production machine (i.e., a Citrix virtual desktop master image) so it's available to any user who logs onto the production machine (i.e., logs on to a virtual desktop based on the master image). The 32-bit version of Word 2013 is installed on the master image.
As I understand it, this means the 'add-in' has to be installed under 'C:\Program Files (x86)' for two reasons:
- So all users have access to the add-in, and
- Under (x86) because it's the 32-bit version of Word).
Also, because all users need to access the add-in
, the required VSTO
registry key settings go under the root HKLM
(and not HKCU
). Essentially, this 'all users' setup is the opposite of the 'one user' Click-Once
setup. Apropos of nothing, I'm in an enclave that is not connected to the Internet. So, all software I use is downloaded elsewhere, and then carried into the enclave and installed locally.
The release files for my VSTO
word add-in (i.e, in C:\....\Visual Studio 2017\Projects\FooAddIn\FooAddIn\bin\Release
) are:
- FooAddIn.dll
- FooAddIn.dll.manifest
- FooAddIn.vsto
- Microsoft.Office.Tools.Common.v4.0.Utilities.dll
What I did
Downloaded and installed 'WiX' v3.11.1 onto my development machine from http://wixtoolset.org/releases/.
Downloaded and installed 'Wix Toolset Visual Studio 2017 Extension' onto my development machine from https://marketplace.visualstudio.com/items?itemName=RobMensching.WixToolsetVisualStudio2017Extension
Opened my add-in
project FooAddIn
using VS 2017
and in Solution Explorer
, right-mouse clicked on the top-line Solution
node and clicked Add -> New Project
.
In the Add New Project
dialog, clicked on v3
under WiX Toolset
and then clicked on Setup Project for WiX v3
. I named the new project FooAddInSetup
. Visual Studio Solution Explorer
shows Solution FooAddIn (2 projects)
, project FooAddIn
, and project FooAddInSetup
.
Under FooAddInSetup -> References
, added references to C:\Program Files (x86)\WiX Toolset v3.11\bin\WixNetFxExtension.dll
and C:\Program Files (x86)\WiX Toolset v3.11\bin\WixUIExtension.dll
(These are needed by elements of the Product.wxs file to build the installer).
Configured VS to also build the setup program: In VS, click on Build -> Configuration Manager. In the Configuration Manager dialog, checked the Build
check box for FooAddInSetup.
Created EULA.rtf
(mine says "This is license-free software") and placed it in C:....\Visual Studio 2017\Projects\FooAddIn\FooAddInSetup
Created a preprocessor variable for the path to the location of my VSTO
release files: In Solution Explorer, right mouse clicked FooAddInSetup -> Properties
. On the FooAddInSetup tab, Clicked on 'Build'. In the General
section, clicked Define 'Debug' preprocessor variable
. In the Define preprocessor variables:
textbox, entered AddinFiles=..\FooAddIn\bin\$(Configuration)\
Populated the boilerplate WiX
Product.wxs
file for my add-in
as shown below under Product.wxs file
Note: In the wxs
file, I modified the Visual Studio 2010 Tools for Office Runtime
hyperlink in the Condition
element - the one in Pieter's example is dead.
I set the Solution Configuration to Release
and built the solution.
Copied FooAddInSetup.msi
from ...\FooAddInSetup\bin\release
on my dev machine to my production machine (the VDI master) and ran the setup program as admin.
Results
Without regard to the registry settings I asserted in the wxs
file, my registry keys were created in HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Office\Word\AddIns\LesCaveatAddIn
, i.e., they went into HKLM as expected, but they went into \Software\Wow6432Node\Microsoft.....
instead of \Software\Microsoft....
as I coded in the wxs
file. I assume this is because my production machine is a 64-bit machine.
As expected, the add-in itself was installed under c:\program files (x86)
Brought up Word, and the add-in was loaded as expected
Product.wxs file
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">
<!--
The boilerplate Product.wxs file already contains the minimum amount of elements needed to build a WiX installer.
If the Product element, Id attribute is set to an asterisk (*), WiX will generate a new GUID every time the setup project is compiled (I left it as-is).
Change the Name attribute value and Manufacturer attribute value to values of your choice.
-->
<Product Id="*"
Name="FOO Add-In"
Language="1033"
Version="1.0.0.0"
Manufacturer="Foo Masters"
UpgradeCode="4b35cc09-4780-4644-a7d4-f5901f7a7e45">
<!--Attributes shown are the minimum number needed to build the setup project.-->
<Package InstallerVersion="200"
Compressed="yes"
InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<!-- Verify if VSTO Office Runtime is installed -->
<Property Id="VSTORUNTIMEREDIST">
<RegistrySearch
Id="VSTORuntimeRedist"
Root="HKLM"
Key="SOFTWARE\Microsoft\VSTO Runtime Setup\v4R"
Name="Version"
Type="raw" />
</Property>
<Condition
Message="The Visual Studio 2010 Tools for Office Runtime is not installed.
Please download and install from https://www.microsoft.com/en-us/download/details.aspx?id=48217.">
<![CDATA[Installed OR VSTORUNTIMEREDIST>="10.0.30319"]]>
</Condition>
<!-- Verify if .NET Framework is installed -->
<PropertyRef Id="NETFRAMEWORK40FULL"/>
<Condition Message="This application requires .NET Framework 4.0.">
<![CDATA[Installed OR NETFRAMEWORK40FULL]]>
</Condition>
<!--I want one Cab file, so only one Media element is needed. Make sure the EmbedCab attribute value is "yes".-->
<Media Id="1" Cabinet="FooAddin.cab" EmbedCab="yes"/>
<!--Set values for display on setup progeam UI-->
<Feature Id="ProductFeature" Title="FOO Add-In" Level="1">
<ComponentGroupRef Id="ProductComponents" />
<ComponentRef Id="Registry_FriendlyName" />
<ComponentRef Id="Registry_Description" />
<ComponentRef Id="Registry_Manifest" />
<ComponentRef Id="Registry_LoadBehavior" />
</Feature>
<!--Specify that the WiXUI_Minimal UI should be used, i.e, the simplest UI available -->
<UIRef Id="WixUI_Minimal" />
<!--Specify the EULA file to use-->
<WixVariable Id="WixUILicenseRtf" Value="EULA.rtf" />
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="FooAddin" />
<!-- Add required VSTO registry entries for 32-bit Word -->
<!-- see https://docs.microsoft.com/en-us/visualstudio/vsto/registry-entries-for-vsto-add-ins?view=vs-2019-->
<Component Id="Registry_FriendlyName">
<RegistryValue Id="RegKey_FriendlyName" Root="HKLM"
Key="Software\Microsoft\Office\Word\AddIns\FooAddin"
Name="FriendlyName"
Value="FOO Add-In"
Type="string" KeyPath="yes" />
</Component>
<Component Id="Registry_Description">
<RegistryValue Id="RegKey_Description" Root="HKLM"
Key="Software\Microsoft\Office\Word\AddIns\FooAddin"
Name="Description"
Value="FOO Add-In"
Type="string" KeyPath="yes" />
</Component>
<Component Id="Registry_Manifest">
<RegistryValue Id="RegKey_Manifest" Root="HKLM"
Key="Software\Microsoft\Office\Word\AddIns\FooAddin"
Name="Manifest" Value="[INSTALLFOLDER]FooAddin.vsto|vstolocal"
Type="string" KeyPath="yes" />
</Component>
<Component Id="Registry_LoadBehavior">
<RegistryValue Id="RegKey_LoadBehavior" Root="HKLM"
Key="Software\Microsoft\Office\Word\AddIns\FooAddin"
Name="LoadBehavior" Value="3"
Type="integer" KeyPath="yes" />
</Component>
</Directory>
</Directory>
</Fragment>
<Fragment>
<!-- Add refs to the components of the VSTO-->
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="MSOfficeToolsCommon_dll_Component">
<File Id="MSOfficeToolsCommon_dll" KeyPath="yes"
Name="Microsoft.Office.Tools.Common.v4.0.Utilities.dll"
Source="$(var.AddinFiles)"></File>
</Component>
<Component Id="FooAddin_dll_Component" >
<File Id="FooAddin_dll" KeyPath="yes"
Name="FooAddin.dll"
Source="$(var.AddinFiles)" />
</Component>
<Component Id="FooAddin_vsto_Component">
<File Id="FooAddin_vsto" KeyPath="yes"
Name="FooAddin.vsto"
Source="$(var.AddinFiles)"></File>
</Component>
<Component Id="FooAddin_dll_manifest_Component">
<File Id="FooAddin_dll_manifest" KeyPath="yes"
Name="FooAddin.dll.manifest"
Source="$(var.AddinFiles)"></File>
</Component>
</ComponentGroup>
</Fragment>
</Wix>
I usually use the Click-Once deployment within Visual Studio. You can deploy it to a network path so other users will be able to install it.
First you want to create a non-expiring certificate for Visual Studio projects
Type Developer Command
in the Start Menu search and right click and select Run as administrator
Paste the following commands in the command prompt for MakeCert and pvk2pfx
MakeCert /n "CN=Your New Cert" /r /h 0 /eku "1.3.6.1.5.5.7.3.3,1.3.6.1.4.1.311.10.3.13" /e "01/01/2100" /sv MyNewCert.pvk MyNewCert.cer
pvk2pfx -pvk MyNewCert.pvk -spc MyNewCert.cer -pfx MyNewCert.pfx
Note:
- The date format is the US standard
MM/DD/YYYY
- The
-f
parameter can be used at the end of the pvk2pfx line for overwriting an existing file
- You'll get prompted to create a password (this is optional)
After the password prompt, you'll need to run the second command line by just pressing the Enter key.
Now you can select the same certificate for multiple Visual Studio projects
In the Visual Studio project properties, select Signing* click on Select from File….
Navigate to the same path from the command prompt and select the certificate file (*.pfx)
Publish the project
Then go to the Publish tab in the project properties and click Publish Now. It will create a executable file in the published location. Then you just need to send a link to the .exe
file to your end-users.