As you’ll have no doubt noticed, when you build and run within Visual Studio, Outlook loads the add-in. This is because building the project includes a step for registration with Outlook. (Doing a “build clean” will, symmetrically, unregister it.) This is fine and dandy if you’re the only user, but obviously you’ll need to wrap it up in some distributable package for deploying to other users, so the final topic in this series is installation.
The good news is that this is very easy within VSTO: right click on the project, select “publish” and click through the wizard – this will create a ClickOnce install package which can be placed on a web server or some file share for people to install from. Of course, that was too easy… There is one thing to take care of before you have a general installer: the components of the install package here are a setup.exe program to get the show on the road and the add-in files themselves; setup.exe includes a list of “prerequisites” to check for and install (from the web, or from a local copy, depending on how you configure the installer) if necessary, before installing the add-in bits. By default, the prerequisite list includes the .NET 4 runtime and a suitably up to date version of Windows Installer (before you scratch your head too much about the recursion there, setup.exe does not itself require Windows Installer, it just makes sure it’s there before invoking it later), but you need to add the VSTO runtime and, if you’re not using type embedding, you also need the Office Primary Interop Assemblies. If you don’t add all the relevant prerequisites, the package will still install, but it’ll only actually run on machines that happen to have the omitted packages already. Head to the publish tab in project properties, click the Prerequisites button and select the items you need.
This approach is probably adequate for a lot of scenarios, and is certainly quick and painless to set up. When an end user installs the package, a dialog box will pop up asking for permission to install the add-in. Some people have asked me about “silent installs” which suit their environment and users better. I don’t know about silent installation for the prerequisites, but the add-in bits consist of a small number of files (the built DLL and some dependencies, and two different manifest files) and a bunch of registry settings which let Outlook work out what to do with those files. Any mechanism that copies the files to somewhere accessible from the end user’s Outlook and writes the handful of registry settings will do (even a .BAT file, though PowerShell might be better these days!), and I’ll offer WiX as an example here. There are numerous tutorials for WiX, so I’ll outline only fragments that refer to content for our add-in, starting with the files:
<Component Id="CMP_NoReply"> <File Id="FILE_NoReply" Source="$(var.SrcDir)NoReplyAddin.dll" KeyPath="yes" /> </Component> <Component Id="CMP_DllManifest"> <File Id="FILE_DllManifest" Source="$(var.SrcDir)NoReplyAddin.dll.manifest" KeyPath="yes" /> </Component> <Component Id="CMP_VstoManifest"> <File Id="FILE_VstoManifest" Source="$(var.SrcDir)NoReplyAddin.vsto" KeyPath="yes" /> </Component> <Component Id="CMP_ToolsCommon"> <File Id="FILE_ToolsCommon" Source="$(var.SrcDir)Microsoft.Office.Tools.Common.v4.0.Utilities.dll" KeyPath="yes" /> </Component> <Component Id="CMP_ToolsOutlook"> <File Id="FILE_ToolsOutlook" Source="$(var.SrcDir)Microsoft.Office.Tools.Outlook.v4.0.Utilities.dll" KeyPath="yes" /> </Component>
Something I’ve noticed with WiX is that the automatic project dependency stuff doesn’t work with VSTO projects, so I have to manually define a variable to locate the binaries (SrcDir here).
The registry settings are:
<Component Id="CMP_Registry"> <RegistryKey Root="HKCU" Key="Software\Microsoft\Office\Outlook\Addins\NoReplyAddin"> <RegistryValue Name="Description" Value="Adds no-replyall and no-forward buttons." Type="string" Action="write" KeyPath="yes" /> <RegistryValue Name="FriendlyName" Value="NoReplyAddin" Type="string" Action="write" KeyPath="no" /> <RegistryValue Name="LoadBehavior" Value="3" Type="integer" Action="write" KeyPath="no" /> <RegistryValue Name="Manifest" Value="[APPLICATIONFOLDER]NoReplyAddin.vsto|vstolocal" Type="string" Action="write" KeyPath="no" /> </RegistryKey> </Component>
The one weird bit there is the “|vstolocal” at the end of the manifest line, which tells Outlook to run the add-in from that location instead of copying it elsewhere. You can also specify HKLM instead of HKCU, which will install the add-in for all users, not just the current one.
Wrap that lot up in the standard WiX project skeleton and you’ll have a UI-less installer. Add a reference to WixUI_Minimal and you have a, well, minimal UI.