WiX Cookbook
上QQ阅读APP看书,第一时间看更新

Using the heat.exe tool to generate components

Sometimes, your software is going to require a lot of files: there's the main executable, supporting libraries, images, configuration files, help documentation, and potentially more. You might start out writing the Component elements by hand, but pretty soon it's going to amount to more than you'd care to take on.

The WiX team has provided a tool called Heat to shoulder the burden. You can take this utility and point it at a directory of files, and it will generate the WiX markup for you. In this recipe, we'll try it out by creating a directory of text files and then run Heat to turn it into a .wxs file. Heat is included in the WiX toolset.

Getting ready

To prepare for this recipe, perform the following steps:

  1. On your desktop, create a folder named SourceFiles.
  2. Add three text files to it and name them Sample1.txt, Sample2.txt, and Sample3.txt.

How to do it…

Call heat.exe from the command line to convert a folder of files into the WiX markup using the following steps:

  1. Open a command prompt and change the directory to your Desktop folder:
    cd Desktop
    
  2. Invoke heat.exe on the folder with the following command:
    "%WIX%bin\heat.exe" dir "SourceFiles" -cg MyComponentGroup -dr INSTALLFOLDER -gg -sfrag -srd -var var.SourceFilesDir -out "Components.wxs"
    
  3. Check that a file called Components.wxs was created on your desktop. Create a new WiX setup project and copy the Components.wxs file into it. You can do this by dragging the file onto the Visual Studio Solution Explorer.
    How to do it…
  4. Define a preprocessor variable called SourceFilesDir as the path to the Desktop\SourceFiles folder by opening your setup project's properties and selecting the Build tab. Then, add SourceFilesDir=C:\Users\Nick\Desktop\SourceFiles to the textbox that's labeled Define preprocessor variables. You can also use a relative path. Use the path to your own Desktop.
    How to do it…
  5. To reference our new components in the project, add a ComponentGroupRef element to our project's Product.wxs file. Its ID should match the ID of ComponentGroup that Heat generated for us in the Components.wxs file:
    <Feature Id="ProductFeature" Title="HeatInstaller" Level="1">
     <ComponentGroupRef Id="ProductComponents" />
     <ComponentGroupRef Id="MyComponentGroup"/>
    </Feature>
    

How it works…

Our call to Heat began with the dir harvest type. The term harvest means to generate WiX markup from a source. There are several things that can be harvested, including Visual Studio projects, single standalone files and, in this case, a whole directory; hence, the dir harvest type is used. Immediately following the harvest type is the directory where the source files can be found. In this case, we named the folder SourceFiles.

The -cg flag instructs heat.exe to create a ComponentGroup element and the Id to assign to it; in this case, we used MyComponentGroup. All the components that Heat generates will be included in this group.

Next, we set the -dr flag to INSTALLFOLDER so that our components can be installed to that directory. The -gg flag generates GUIDs for the components. The -sfrag flag causes all the components to be put into a single Fragment tag, rather than having each in its own Fragment tag. The -srd flag tells Heat to not create a Directory element with the name SourceFiles, which it would have done otherwise.

The -var flag causes each File element to have a Source attribute prefixed with a preprocessor variable of our choice. Here's an example of a File element that would be generated that is prefixed with the SourceFilesDir variable that we specified:

<File Id="filB6C392508320F3B45A8928D279282132" 
      KeyPath="yes" 
      Source="$(var.SourceFilesDir)\Sample2.txt" />

Having this variable in place allows us to specify the path to our text files dynamically by setting its value in the WiX setup project's properties. The last flag we used was -out, which gives a name to the .wxs file that Heat generates.

We copied the Components.wxs file to a setup project and defined the SourceFilesDir preprocessor variable so that it pointed to the folder on our desktop. The reason that we need to do this is that the .wxs file only contains markup to add the files. The actual source files themselves must still be linked-in during compilation. Finally, we added a ComponentGroupRef element within our Feature so that the new components would be included in the MSI.

There's more…

In this recipe, we did all of our work from the command line. We can do the same job within a setup project's .wixproj file using the MSBuild syntax. That way, the latest files will be pulled in each time we build the project. The key is to use the HeatDirectory task.

Here's an example where we've added a HeatDirectory task inside of the BeforeBuild target in our .wixproj file:

<Target Name="BeforeBuild">
  <PropertyGroup>
    <WixToolPath>C:\Program Files (x86)\WiX Toolset  v3.8\bin\</WixToolPath>
  </PropertyGroup>
  <HeatDirectory ToolPath="$(WixToolPath)"
                 Directory="$(ProjectDir)SourceFiles"
                 ComponentGroupName="MyComponentGroup"
                 DirectoryRefId="INSTALLFOLDER"
                 GenerateGuidsNow="true"
                 SuppressFragments="true" 
                 SuppressRootDirectory="true" 
                 PreprocessorVariable="var.SourceFilesDir" 
                 OutputFile="Components.wxs" />
</Target>

As before, the SourceFilesDir preprocessor variable would need to be defined in the project's properties and MyComponentGroup should be added as ComponentGroupRef within the feature. Also, we will need to add the Component.wxs file to the project after the first time that it's generated. From then on, it will be automatically updated for you each time you build the project.

Note

If you're using a version control system such as TFS that locks your files between checkouts, you may not want to check-in the Components.wxs file itself, since it will constantly change.

More information about the HeatDirectory task can be found at http://wixtoolset.org/documentation/manual/v3/msbuild/task_reference/heatdirectory.html.