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
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
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
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
Name="BeforeBuild"> tag (you might have to add this tag if it's not already
<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
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.
The other parameters that can be passed to the
GenerateExternalIds(bool) - Whether to generate random component ids for components that are external dependencies (files that are not project outputs). Defaults to
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
falseif you want to easily reference certain files in other components.
GenerateGuids(bool) - Whether to generate the WIX Guids used for the components. Defaults to
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!
The WIXProjectDependencies task can be found on GitHub. Any comments or improvements are appreciated!