How to Build Visual Studio Installer Projects in Azure Pipelines

In a previous post, I mentioned I recently started working on a legacy WPF application. Before adding new features, we wanted to ensure that tests would cover the current functionality and that we could reliably build it for distribution. Since it was configured as a Visual Studio Installer Project, it made creating an Azure Pipeline more difficult than I originally anticipated.

Keep these tips in mind if you want to create a CI pipeline for your own Visual Studio Installer Project.

Choosing a hosted agent

If you have yet to work on a Visual Studio Installer Project, you’ll need to download the Visual Studio extension before you can build your app. The 2022 version of the extension adds the VSInstallerProjects2022 component to Visual Studio, allowing the Visual Studio process to build .vdproj projects.

When creating an Azure Pipeline, you can use your own self-hosted agents or one of the Microsoft-hosted agents already pre-configured with a set of tools. Currently, both windows-2022 and windows-2019 Microsoft-hosted agents have the VSInstallerProjects2022 component available to help with building Visual Studio Installer Projects. However, you’ll need to take care of a few more required steps before building the project.

Finding the tools

You can’t open Visual Studio directly in an Azure Pipeline to build the .vdproj project. Because of this, you’ll need to use the tooling that Visual Studio uses internally to build the installer. Attempting to build the .vdproj project with MSBuild directly will fail since MSBuild does not support this project type.

Visual Studio uses the devenv executable internally to build .vdproj projects. This executable is located at a file path similar to the following:

C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE

Attempting to use devenv.exe directly from your terminal will not work. You will need to use the provided devenv.com executable, intended to be used from the command line.

Now that we have a hosted agent with the correct tooling and we know which tools to use to build the project we should be all set! But of course, there is one additional step that we need to take first.

Overriding default configurations

Visual Studio Installer Projects were originally meant to be built directly from Visual Studio. To build a .vdproj file outside of Visual Studio, you have to add a registry key to disable this limitation. Microsoft provides an executable with Visual Studio called DisableOutOfProcBuild which will update this registry key and allow you to build the .vdproj project from the command line.

This executable is typically located in a file path similar to the following path:

C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\VSI\DisableOutOfProcBuild

The exact file path is dependent on the version of Visual Studio you have. I found it best to navigate to that folder path in my terminal before running the executable otherwise it will throw an error.

Once you’ve disabled the registry key to allow “out of process” builds of .vdproj projects, you can now freely build your Visual Studio Installer Project from the command line!

Bringing it all together

Here is a sample Azure Pipeline config that brings all of these steps together.


trigger:
- '*'

pool:
  vmImage: 'windows-2022'

variables:
  solution: '**/MySolution.sln'
  buildPlatform: 'Any CPU'
  devCmd: 'C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\devenv.com'
  disableToolPath: 'C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\VSI\DisableOutOfProcBuild'
  
steps:
- task: NuGetToolInstaller@1
- task: NuGetCommand@2
  displayName: Restore NuGet packages
  inputs:
    restoreSolution: '$(solution)'

# https://github.com/it3xl/MSBuild-DevEnv-Build-Server-Workarounds/issues/1#issuecomment-525435637
- task: BatchScript@1
  displayName: Enable .vdproj Builds
  inputs:
    filename: '"$(disableToolPath)\DisableOutOfProcBuild.exe"'
    workingFolder: '"$(disableToolPath)"'

- script: '"$(devCmd)" $(System.DefaultWorkingDirectory)\MySolution.sln /Build "Release" /Project $(System.DefaultWorkingDirectory)\Installer\MyInstaller.vdproj'
  displayName: Build Installer

From here, you could publish the release artifacts or whatever else you might need your pipeline to do.

I hope this post has helped you in some way. Please feel free to comment below with anything that I might have missed!

Conversation
  • reliantbay says:

    I have a custom nuget repository that i am using from azure artifacts .how do i tell the devenv.com to use a custom nuget feed instead of nuget.org. it is failing to build as some of the packages are only in our private feed.

    – task: NuGetCommand@2
    displayName: Restore NuGet packages
    inputs:
    restoreSolution: ‘$(solution)’
    vstsFeed: ‘mycustomfeedidhere’
    includeNuGetOrg: false

  • Comments are closed.