Referencing the output of a .NET console application in a WiX project by using a preprocessor variable
After setting up our WiX project, the first thing we'll probably want to do is package up the files that we plan to install. Since we're working in Visual Studio, we'll likely want to include the output of other projects such as the .exe
file that's created from a console application project. At first, we could try hardcoding the path to the file:
<Component Id="cmpMyConsoleAppEXE"
Guid="{882DB6AA-1363-4724-8C43-2950E7ABECD4}">
<File Source="..\MyConsoleApp\bin\Debug\MyConsoleApp.exe" />
</Component>
Although this works, it's a bit brittle and will break if the path to the file changes. Instead, we can use a preprocessor variable to store the path and allow Visual Studio to keep it up-to-date through the power of project references. In this recipe, we'll reference a console application's output and use a preprocessor variable to include that output in our installer.
Getting ready
To prepare for this recipe, create a new WiX setup project and name it ConsoleAppInstaller
.
How to do it…
Use a preprocessor variable to get the path to a project's output with the following steps:
- Add a new C# console application to the same solution as the
ConsoleAppInstaller
setup project by right-clicking on the solution in Solution Explorer, going to Add | New Project… | Visual C# | Console Application and naming itTestApplication
. The name matters as we'll be referencing it later: - Within the setup project, add a reference to
TestApplication
by right-clicking on the References node in Solution Explorer, choosing Add Reference..., and findingTestApplication
under the Projects tab. Click on Add and then on OK: - Within the setup project, open
Product.wxs
and replace theComponentGroup
markup inside the last fragment with the following code:<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER"> <Component Id="cmpTestApplicationEXE" Guid="{6E2A6370-4784-4CF3-B42B-AA2D29EA5B1B}"> <File Source="$(var.TestApplication.TargetDir)TestApplication.exe" /> </Component> </ComponentGroup>
- Build the project and
TestApplication.exe
will be included in the MSI file. Note that you must set theEmbedCab
attribute on theMediaTemplate
element toyes
to include the CAB file that WiX creates, which is where our.exe
file is stored, inside the MSI. Also, this example assumes thatTestApplication.exe
is the only file you'd like to include in the installer. Other files, such as DLLs, can be included in the same way though.
How it works…
When we referenced the C# console application within the WiX setup project, the preprocessor variable $(var.[ProjectName].TargetDir)
was made available to us, where ProjectName
in this case is TestApplication
. TargetDir
points to the output directory of the console application project where our compiled TestApplication.exe
file can be found.
Other preprocessor variables are also made available. For example, $(var.[ProjectName].TargetFileName)
gives you the name of the compiled application, which for us would be TestApplication.exe
. A full list of these variables can be found at http://wixtoolset.org/documentation/manual/v3/votive/votive_project_references.html.
Another benefit of referencing the console application project in this way is that it ensures it is compiled before our setup project is. This way, our installer always includes the most up-to-date version of the application.
Note
The GUID used for the Guid
attribute on the Component
element in this example can be any GUID, not just the one listed. You can generate a new one in Visual Studio by navigating to Tools | Create GUID. Use Registry Format as the GUID's format. More information can be found at http://wixtoolset.org/documentation/manual/v3/howtos/general/generate_guids.html.
You can also set the Guid
attribute to an asterisk (*
) or omit it altogether and WiX will set the GUID for you. You should choose your own if you plan on authoring a patch file for the application in the future or if the contents of Component
don't contain an element that can be marked as a KeyPath
element.