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 totrue
. Iffalse
, 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 tofalse
, meaning the filename will be used as the component id. It is useful to leave thisfalse
if you want to easily reference certain files in other components. -
GenerateGuids
(bool) - Whether to generate the WIX Guids used for the components. Defaults totrue
.
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