Pieter van der Westhuizen

Creating WiX installation projects for VSTO-based Office add-ins

In the last two articles, I’ve shown you how to create a WiX installer for Add-in Express based add-ons from scratch and how to convert your existing setup projects (vdproj) to WiX. In this blog, I’ll show you how to create a WiX installer for Visual Studio Tools for Office (VSTO) based Office add-in projects.

Creating the VSTO add-in for Office Excel 2010

Before we can build an installer, we need to create a new Excel 2010 Add-in project in Visual Studio.

Creating a new Excel 2010 Add-in project in Visual Studio

We’ll keep things simple as the add-in will only add a new tab to the Excel ribbon with a button.  To do this you’ll need to add a new Ribbon to your add-in project.

Adding a new Ribbon to your Excel add-in

Creating the WiX installation project

Before you can create a new WiX setup project, the WiX Toolset should be installed first. Once the WiX Toolset is installed you’ll see a list of WiX project types in Visual Studio.

WiX project types in Visual Studio

Select the WiX Setup Project and add it to your Visual Studio Solution. The installation package will only contain one file called Product.wxs; this file is what we’ll use to create the installer for our VSTO based Excel add-in.

Product and Package element

When you open the Product.wxs file in Visual Studio you’ll notice that the file already contains the minimum amount of elements in order to build a WiX installer. The first element of importance is the Product element, keep the Id attributes’ value as it is. If the value is set to an asterisk (*), WiX will generate a new GUID every time the setup project is compiled. Next, change the Name attributes’ value to the name of your plug-in and Manufacturer to your company name.

Leave the Package element as is, it contains the minimum amount of attributes for the setup project to build.

<Product Id="CE2CEA93-9DD3-4724-8FE3-FCBF0A0915C1" 
         Name="My Excel Add-in" 
         Language="1033" 
         Version="1.0.0.0" 
         Manufacturer="My Software Company" 
         UpgradeCode="7b3b630d-c617-419f-8272-95942cf21420">
 
<Package InstallerVersion="200" 
         Compressed="yes" 
         InstallScope="perMachine" />

ComponentGroup and Component elements

The ComponentGroup element is where you add all the files you need your add-ins’ installer to copy to the target pc. It is a good rule of thumb to only include one File element inside a Component element, reason being  that when you set the File element’s KeyPath attribute to yes and the user does a repair the file will be replaced, if more than one file is inside the Component element, they will not be replaced by a repair.

The ComponentGroup/Component elements for a simple VSTO add-in project would look similar to the following code listing:

<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
  <Component Id="ExcelAddin1_vsto_Component">
    <File Id="ExcelAddin1_vsto" KeyPath="yes"
          Name="ExcelAddin1.vsto" Source="$(var.AddinFiles)"></File>
  </Component>
  <Component Id="ExcelAddIn1_dll_manifest_Component">
    <File Id="ExcelAddIn1_dll_manifest" KeyPath="yes"
          Name="ExcelAddIn1.dll.manifest" Source="$(var.AddinFiles)"></File>
  </Component>
  <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="MSOfficeToolsExcel_dll_Component">
    <File Id="MSOfficeToolsExcel_dll" KeyPath="yes"
          Name="Microsoft.Office.Tools.Excel.dll"
          Source="$(var.AddinFiles)"></File>
  </Component>
  <Component Id="ExcelAddIn1_dll_Component" >
    <File Id="ExcelAddIn1_dll" KeyPath="yes"
          Name="ExcelAddIn1.dll" Source="$(var.AddinFiles)" />
  </Component>
</ComponentGroup>

The $(var.AddinFiles) variable is declared by right-clicking on your setup project in the Visual Studio Solution Explorer and selecting Properties.  You then need to add the following to the “Define preprocessor variables” field:

AddinFiles=..\ExcelAddIn1\bin\$(Configuration)\

Defining the required preprocessor variable

Directory element

We’ll keep the default Directory element as is, and only change its Name attribute to something more descriptive. You’ll also need to add all registry entries inside the Directory element, if this is not done, your VSTO add-in will not load at all!

<Directory Id="TARGETDIR" Name="SourceDir">
  <Directory Id="ProgramFilesFolder">
    <Directory Id="INSTALLFOLDER" Name="MyExcelAddin" />
    <Component Id="Registry_FriendlyName">
      <RegistryValue Id="RegKey_FriendlyName" Root="HKCU"
                     Key="Software\Microsoft\Office\Excel\AddIns\ExcelAddIn1"
                     Name="FriendlyName"
                     Value="My Excel Add-In"
                     Type="string" KeyPath="yes" />
    </Component>        
    <Component Id="Registry_Description">
      <RegistryValue Id="RegKey_Description" Root="HKCU"
                     Key="Software\Microsoft\Office\Excel\AddIns\ExcelAddIn1"
                     Name="Description"
                     Value="My very cool Excel Add-In"
                     Type="string" KeyPath="yes" />
    </Component>
    <Component Id="Registry_Manifest">
      <RegistryValue Id="RegKey_Manifest" Root="HKCU"
                     Key="Software\Microsoft\Office\Excel\AddIns\ExcelAddIn1"
                     Name="Manifest" Value="[INSTALLFOLDER]ExcelAddIn1.vsto|vstolocal"
                     Type="string" KeyPath="yes" />
    </Component>
    <Component Id="Registry_LoadBehavior">
      <RegistryValue Id="RegKey_LoadBehavior" Root="HKCU"
                     Key="Software\Microsoft\Office\Excel\AddIns\ExcelAddIn1"
                     Name="LoadBehavior" Value="3"
                     Type="integer" KeyPath="yes" />
    </Component>
  </Directory>
</Directory>

The following registry key will be created when the user installs your Office add-in:

HKEY_CURRENT_USER\Software\Microsoft\Office\Excel\AddIns\ExcelAddin1

Feature element

You can set the Feature element’s Title attribute’s value to a more friendly human readable value. In this example we’ll rename it to “My Excel Add-in”.  We’ll also add the registry components, we’ve added in the Directory element, to the Feature element.

<Feature Id="ProductFeature" Title="My Excel Add-in" Level="1">
  <ComponentGroupRef Id="ProductComponents" />
  <ComponentRef Id="Registry_FriendlyName" />
  <ComponentRef Id="Registry_Description" />
  <ComponentRef Id="Registry_Manifest" />
  <ComponentRef Id="Registry_LoadBehavior" />
</Feature>

Media element

Since we only want one Cab file, we only need to add one Media element to the WiX source file. Make sure you set the EmbedCab attribute’s value to yes.

<Media Id="1" Cabinet="ExcelAddin1.cab" EmbedCab="yes"/>

Defining Prerequisites

We need to check whether the Microsoft .Net Framework and the Visual Studio 2010 Tools for Office Runtime are installed on the target PC or our Excel add-in will not work. To do this, you’ll need to add two Conditions:

  1. To check whether the VSTO Office Runtime is installed, we’ll add condition and two RegistrySearch elements. RegistrySearch, does exactly what the name implies, it searches the target machines’ registry for a specific key and value.
<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 
  http://www.microsoft.com/en-us/download/details.aspx?id=20479.">
  <![CDATA[Installed OR VSTORUNTIMEREDIST>="10.0.30319"]]>
</Condition>

To check whether .Net Framework 4 is installed, we need to add a PropertyRef element and another condition.

<PropertyRef Id="NETFRAMEWORK40FULL"/>
<Condition Message="This application requires .NET Framework 4.0.">
  <![CDATA[Installed OR NETFRAMEWORK40FULL]]>
</Condition>

You’ll also need to add a reference to the WixNetFxExtension.dll assembly, you can read more about WixNetFxExtension  and how it can help you on its SourceForge page.

Setting the User Interface and License agreement text of the WiX installation package

Finally, we need to add two elements to our installation; one will specify which UI to use for our setup and the other which file the installer should use for our End-User License Agreement (EULA).

We’ll use the simplest UI available to us called WiXUI_Minimal:

<UIRef Id="WixUI_Minimal" />

To use your own license agreement, add a new Rich Text file (.rtf) to the setup project of your addin that contains the licensing text you require and add the following element to your WiX source file:

<WixVariable Id="WixUILicenseRtf" Value="EULA.rtf" />

Before you build and test your setup project you’ll need to add a reference to the WiXUIExtension.dll file, which you’ll find in the WiX install folders’ bin folder.

Building and running the setup

With the necessary configuration in place, you can build your WiX setup project. It should produce a .msi file, which when run will display the following screen:

The setup wizard in action

There you have it; you’re VSTO add-in will be installed and with the correct registry keys in place, it will be registered with Microsoft Excel 2010.

Thank you for reading. Until next time, keep coding!

Updated on 21-Feb-2013:

If you want to change your existing Visual Studio setup projects to WiX, check out our new tool – VDProj to WiX Converter. This extension for Visual Studio 2012-2005 lets you convert your vdproj setups  to WiX in 1 click!

Available downloads:

A sample WiX installation project for Excel add-in.

23 Comments

  • https://secure.gravatar.com/avatar/0ae4c25b257d2e8f04909dc637f6df6f?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Lewis says:

    Great article, is it possible to pass variables from WiX to a vsto add in?

    Example I have created an addin which just creates a new meeting request. What I need is for during the install the user to enter their desk extension and then have this number in the subject of the meeting request.

    Any idea how to achieve this?

    Thanks

    Lewis

  • https://secure.gravatar.com/avatar/e1a4c2b21a5186e0b27c1c601f418b76?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Pieter van der Westhuizen says:

    Hi Lewis,

    Yes, it can be done. You need to save the variables to the registry and read it from the registry ones your add-in is running.

    To give you a rough idea, you need to add a UI with a Property e.g:

    <UI Id='CustomDlg'>
      <Property Id='CHKBOXVAL' Value='1' />
      <Dialog Id='CustomCheckA' X='50' Y='50' Width='373' Height='287' Title='[ProductName]'>
      <Control Id='Checkbox1' Type='CheckBox' X='18' Y='108' Width='348' Height='12'
        Text='Enable Feature X' TabSkip='no' Property='CHKBOXVAL' CheckBoxValue='1' />
    ...
    </UI>

    Then you can save it to the registry:

    <ComponentGroup Id='RegistryGroup'>
      <Component Id='_D27BF2B1_E6A0_47FB_B609_F7463D9CBCF4'
        Guid='082B6211-B9AC-4092-BF05-CA62C787C005' Transitive='no' Directory='TARGETDIR'>
        <Condition><![CDATA[CHKBOXVAL]]></Condition>
        <RegistryValue Root=&#039;HKCU&#039; Key=&#039;Software\[Manufacturer]&#039; 
          Type=&#039;integer&#039; Name=&#039;EnableFeatureX&#039; Value=&#039;1&#039; />
      </Component>
    ...
    </ComponentGroup>

    Hope this helps and thanks for your comment!

  • https://secure.gravatar.com/avatar/24dcc28243287c6b548dc91a0cdca753?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Jaymik says:

    Is it possible to install the files to any other folder except that from the default directory folders like ProgramFilesFolder??

  • https://secure.gravatar.com/avatar/e1a4c2b21a5186e0b27c1c601f418b76?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Pieter van der Westhuizen says:

    Hi Jaymik,

    You can use the UIRef element to specify a UI that prompts the user where they would like to install to.
    WiX provides a number of pre-build UI’s:

    WixUI_Mondo
    WixUI_Advanced
    WixUI_FeatureTree
    WixUI_InstallDir
    WixUI_Minimal

    The simplest way to allow a user to choose an installation folder is to use the WixUI_InstallDir dialog sequence.
    You can read more about this in the WiX manual http://wix.sourceforge.net/manual-wix2/WixUI_dialog_library.htm

    Good Luck!

  • https://secure.gravatar.com/avatar/24dcc28243287c6b548dc91a0cdca753?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Jaymik says:

    Hello,

    Thanks for your reply. It really helped me a lot to solve my issue. I would like to get the pre requisite (.NET 4.0 and VSTO) automatically downloaded if not available in user system. The prerequisite should get directly downloaded from web link. You help would be highly appreciated. Thanks in Advance.

  • https://secure.gravatar.com/avatar/e1a4c2b21a5186e0b27c1c601f418b76?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Pieter van der Westhuizen says:

    Hi Jaymik,

    Glad I could help!
    Have a look at the following article that describes how to install the .Net framework with WiX : http://wix.sourceforge.net/manual-wix3/install_dotnet.htm

    Good luck!

  • https://secure.gravatar.com/avatar/24dcc28243287c6b548dc91a0cdca753?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Jaymik says:

    Hello,

    Thanks for the link it did clear the basics, but in our case we need to download .NET 4.0 Client Profile and VSTO. Not sure how can I use remotepayload element. Any help would be appreciated.Thanks

  • https://secure.gravatar.com/avatar/24dcc28243287c6b548dc91a0cdca753?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Jaymik says:

    Hi,

    I have tried adding the boot strapper project and it did run perfectly fine, but the installer wizard(WixUI_Minimal Wizards) does not show up after pre requisite are installed, it directly installs the application. not sure what am I doing wrong. Also Tried in the sample project but still its not working. Any Help would be great.

  • https://secure.gravatar.com/avatar/e1a4c2b21a5186e0b27c1c601f418b76?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Pieter van der Westhuizen says:

    Hi Jaymik,

    Sounds like something is probably missing in the project that causes WixUI_minimal not to show. What do you want to show?

    How exactly is it going wrong? Maybe share your sample project with us?

  • https://secure.gravatar.com/avatar/10bfbb2c24e45e5bc9b7f4665703f7bd?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Ishmaeel says:

    “The first element of importance is the Product element, keep the Id attributes’ value as it is.”

    This might no longer be good advice, I found that the latest version creates the project with a product Id of “*”. You might want the reword that paragraph to stress that Id should not be left as “*” but must contain a fixed GUID for your product. Perhaps a little note clarifying that an auto-generated GUID will prevent proper updates and may lead to duplicate entries in the add/remove programs folder after multiple installations.

  • https://secure.gravatar.com/avatar/e1a4c2b21a5186e0b27c1c601f418b76?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Pieter van der Westhuizen says:

    Hi Ishmaeel,

    The ID must vary for different versions, so by setting it to * it will be unique for each installer package.
    It should not lead to duplicate entries in the Add/Remove window if you make sure to increment the version number in the .wxs file.

    Or am I missing the point? :)

  • https://secure.gravatar.com/avatar/20850f81f5c26ace2c04836bb3ee3703?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Nick says:

    So this tutorial was great but I am running into a problem. I created the Add-iN in Visual Studio on one computer. It consists of a ribbon and a collection of buttons that open various task panes. When I run the Add In on the computer on which I created it, it works fine. However, I then installed it on a 2nd computer using the .msi. The Add-In shows up in Excel, but none of the buttons do anything. I even tried creating a MessageBox popup on the DataLoaderRibbon_Load event, but that does not do anything. Is there some additional security setting I need to change or something along those lines?

  • https://secure.gravatar.com/avatar/e1a4c2b21a5186e0b27c1c601f418b76?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Pieter van der Westhuizen says:

    Hi Nick,

    This is a strange problem. Please send us an email with the project that is giving you the problem and we’ll have a look at it. You can find out support email address in the ADX readme file.

  • https://secure.gravatar.com/avatar/20850f81f5c26ace2c04836bb3ee3703?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Nick says:

    I was able to figure out the problem. The add-in was actually throwing an exception due to a configuration issue unrelated to your example. However, there was no way to know an exception was being thrown until I caught it and displayed the error in a MessageBox. Thank you for offering to help though!

  • https://secure.gravatar.com/avatar/895c19fe69ff50ee551fdec5ad47e139?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Marty T says:

    Hi,

    I just used this article to successfully create an installer for our Word 2013 Add-In.
    Many thanks for sharing the knowledge!

    Best Regards,

    Marty

  • https://secure.gravatar.com/avatar/7aee18a0b5e9d1e2947930ee5f724c45?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Stefan says:

    Hi Pieter, thanks for a great article. I’m not sure where to place the “” code and the code in the following 3 code boxes. Should they go in their own tags in Product.wxs, or should the be part of one of the existing tags?

  • https://secure.gravatar.com/avatar/ab4ec2858cfdf1e44dadf8c50fae314d?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Dmitry Kostochko (Add-in Express Team) says:

    Hi Stefan,

    Sorry, I don’t see the XML code in your comment. Could you please clarify what exactly code you are interested in?

  • https://secure.gravatar.com/avatar/db1c3b651af1b602932a3e443972d71a?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Kunal Gupta says:

    In my Excel Add-in project i am reading some data from the app.config file, but while installing it through Wix,my add-in is not reading the data from the config file, even though i am installing the config file as well with the installer. I don’t know what i am missing here. i don’t have much experience using Wix Installer, and all the googling didn’t give nay fruitful results. Please help me out here.

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    Hello Kunal,

    Make sure that the config file name is {assembly name}.dll.config and it is located in the folder where {assembly name}.dll is located.

  • https://secure.gravatar.com/avatar/db1c3b651af1b602932a3e443972d71a?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Kunal Gupta says:

    Hello Andrei,

    I did exactly that but it is still not working, i suppose it is something to do with the way i am installing the config file.The following is the code i am using to add the config file. It is last second component in the component group.
    Also the path of AddinFILe is ../iFMExcelAddIn/$(Configuration)/. I hope this much info helps let me know if you need more.

  • https://secure.gravatar.com/avatar/db1c3b651af1b602932a3e443972d71a?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Kunal Gupta says:
  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    Kunal,

    If you use Add-in Express, please send me your project (or any other project reproducing this issue) to the support email address (see readme.txt).

  • https://secure.gravatar.com/avatar/ad516503a11cd5ca435acc9bb6523536?s=32 gion says:

    This was very helpful. Thank you!

Post a comment

Have any questions? Ask us right now!