Skip to main content

WIX Project Dependency Task

The WIX framework is excellent for building installers and deploying software for Windows, however there's some functionality that is left to be desired, especially when it comes to deploying projects and ensuring that everything that project needs is bundled. The WIX heat tool can do some helpful things for your deployment, but if you don't want all your projects to build into a single directory, and then use that directory when invoking heat, you need something a bit smarter.

I have developed a Task that can be used in MSBuild to scan the dependencies of a WIX installer project and create an appropriate .wxs file for inclusion in the project. The output file ensures that all dependencies (of C# and C++ projects) are included in the installer.

Using the Task

If you've never integrated a custom Task into your MSBuild-based project (which includes Visual Studio solutions), it's not hard to do. You need to setup a normal C# project which generates a DLL and add the custom task (or tasks, if you create more) to it. Then just build the DLL.

Note that the MSBuild system will hold on to the DLL when using Visual Studio (preventing it from being overwritten), so you can't expect to include the build task project within your normal solution if using VS, since making changes to the project will cause a rebuild, but the build will not be able to write to the output file!

By the way, I recommend using custom tasks for anything non-trivial, over putting complicated and probably more error-prone code in PreBuild and PostBuild steps. The tasks integrate much better into the build system and the dependency system.

Once you have a build task project that can be built into a DLL, you can load that DLL from within MSBuild project files and access the custom tasks that are within it. To edit an MSBuild project file within Visual Studio, you can right-click the project and select Unload Project. Then you can right-click the project again and choose Edit (project file). After making changes, simply right click and select Reload Project.

To load the build task DLL in a project file, add the following:

<UsingTask AssemblyFile="BuildTasks.dll"
           TaskName="BuildTasks.CustomTask" />

anywhere within the root Project tag, assuming that the project DLL is BuildTasks.dll relative to the project directory, and the TaskName is BuildTasks.CustomTask. You can repeat this for other tasks within the DLL if need be.

Adding the WixProjectDependencies Task

Load a DLL containing the WIXProjectDependencies task into the WIX project file, based on the directions above.

Then edit the WIX installer project file and add the following to the <Target Name="BeforeBuild"> tag (you might have to add this tag if it's not already there):

<WIXProjectDependencies ProjectFile="$(MSBuildProjectFile)"
                        OutputFile="Deps.wxs"
                        Configuration="$(Configuration)" />

This will automatically use the dependencies that are listed in that project file itself to generate a dependency tree of output from the projects, and then create a Deps.wxs file that contains those dependencies as WIX components.

While you're editing the project file, it might be useful to add in

<ItemGroup>
  ...
  <Compile Include="Deps.wxs" />
</ItemGroup>

This can of course be added through the Visual Studio GUI after the file has been generated for the first time.

Parameters

The other parameters that can be passed to the WIXProjectDependencies object are:

  • GenerateExternalIds (bool) - Whether to generate random component ids for components that are external dependencies (files that are not project outputs). Defaults to true. If false, the filename will be used as the component id.
  • GenerateInternalIds (bool) - Whether to generate random component ids for components that are internal dependencies (files that are project outputs, and thus internal to the solution/build environment). Defaults to false, meaning the filename will be used as the component id. It is useful to leave this false if you want to easily reference certain files in other components.
  • GenerateGuids (bool) - Whether to generate the WIX Guids used for the components. Defaults to true.

Conclusion

Using this task, roots of the dependency tree can be added simply by adding projects as dependencies of the WIX installer project (which is pretty intuitive in my opinion).

Now as you update and change project dependencies, the installer will appropriately include them. This makes it much easier to prevent creating an installer only to later find that you forgot to include some DLL or other!

Download

The WIXProjectDependencies task can be found on GitHub. Any comments or improvements are appreciated!

Comments