Book Image

WiX Cookbook

By : Nicholas Matthew Ramirez
1 (1)
Book Image

WiX Cookbook

1 (1)
By: Nicholas Matthew Ramirez

Overview of this book

Table of Contents (20 chapters)
WiX Cookbook
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Separating a portion of WIX markup into its own library


As a project grows in complexity and size, we may end up with different teams building different parts of the software in relative isolation. Each team may want to control how their module will be installed or, during development, install only the modules that their code depends upon into their dev environment. To handle these scenarios, we can split our installer into chunks of WiX code called setup libraries.

A setup library can be compiled independently and plugged into the main, monolithic setup project later. We can also include the library in a team-owned setup project that only contains the modules required by the team. In essence, we can mix and match libraries wherever we need them to create installers for different purposes.

You might also want to share some complex installer markup, such as a user interface, with other installers, and a library is the perfect way to do this. Although it's outside the scope of this book, setup libraries are also used when building custom WiX extensions. In this recipe, we'll see how to create a setup library and include it in our setup project.

Getting ready

To prepare for this recipe, create a setup project and call it SetupLibraryInstaller.

How to do it…

Add a setup library to the solution and reference it in a setup project. The following steps show how to do this:

  1. Add a new setup library to the same solution as the setup project by right-clicking on the solution in Solution Explorer and navigating to Add | New Project... | Windows Installer XML | Setup Library Project. For this example, name the project MySetupLibrary:

  2. After it's created, right-click on the MySetupLibrary project in Solution Explorer and go to Add | New Item… | Text File. Name the text file SampleTextFile.txt and click on Add. Our library will install this single text file.

  3. Right-click on the MySetupLibrary project in Solution Explorer again and select Properties. Select the Tool Settings tab and add -bf, which stands for bind files, to the librarian textbox, as shown in the following screenshot:

  4. Open Library.wxs and replace the existing markup with the following:

    <?xml version="1.0" encoding="UTF-8"?>
    <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
      <Fragment>
        <DirectoryRef Id="INSTALLFOLDER">
          <Directory Id="SampleComponentsDirectory" 
            Name="Sample Components" />
        </DirectoryRef>
        
        <ComponentGroup Id="SampleComponentGroup" 
          Directory="SampleComponentsDirectory">
          <Component Id="cmpSampleTextFileTXT" 
            Guid="{5382BC02-4484-4C9B-8734-A99D20632EA9}">
            <File Source="SampleTextFile.txt" />
          </Component>
        </ComponentGroup>
    
        <Feature Id="SampleFeature">
          <ComponentGroupRef Id="SampleComponentGroup" />
        </Feature>
      </Fragment>
    </Wix>
  5. In the SetupLibraryInstaller project, add a reference to the setup library by right-clicking on the References node in Solution Explorer and selecting Add Reference…. Click on the Projects tab, highlight MySetupLibrary, click on Add, and then on OK.

  6. Open Product.wxs and add a FeatureRef element with an ID of SampleFeature. This includes the feature we added to the Library.wxs file of SetupLibrary in our installer. FeatureRef can go after the existing Feature element as follows:

    <Feature Id="ProductFeature" 
             Title="ConsoleAppInstaller" 
             Level="1">
      <ComponentGroupRef Id="ProductComponents" />
    </Feature>
    <FeatureRef Id="SampleFeature"/>

How it works…

Our setup library contains WiX markup to install a single text file called SampleTextFile.txt. Ordinarily, when you build a library like this, the source files don't get stored within it. Instead, only the WiX markup is compiled without any of the source files it refers to. In that case, we would have had to copy SampleTextFile.txt to the setup project's directory too, so that it can be found at link-time when compiling the installer.

However, because we added the -bf flag, which stands for bind files, to the Librarian settings, the text file was serialized and stored within the library. The -bf flag will handle serializing and storing any type of file including executables, images, and other binary data. Setup libraries are compiled into files with a .wixlib extension.

The markup we added to the library created a component, directory, and feature for the text file. To integrate the new directory with the existing directory structure as defined by our setup project, we chose to reference INSTALLFOLDER with a DirectoryRef element. Just be sure that there's a corresponding Directory element in your setup project that has this name. At link time, the DirectoryRef element in the library is merged with the Directory element in the setup project by matching their IDs. Once we had this, we were able to add a new subdirectory within the INSTALLFOLDER directory called Sample Components. After installation, we can see that the new directory was created and it contains our text file:

To be sure that our library gets compiled before our setup project, we referenced it within the setup project using the References node. Then, to create a link to the library, we included a FeatureRef element in Product.wxs, which had an ID matching the Feature defined in the library. This pulls the Feature with all of its components into the installer.

There's more…

The setup libraries might contain more than just components, features, and directories. For example, they might define markup for a user interface using a UI element, which could then be linked to our installer with a UIRef element. Basically, if you can find a corresponding *Ref element, such as DirectoryRef, UIRef, ComponentGroupRef, or FeatureRef, then you'll be able to separate that type of element into a library and use its *Ref element to link it to the setup project.

Even if you can't find a corresponding *Ref element, as long as you have a reference of some kind, such as Property and PropertyRef, the rest of the elements in the library will be carried along with it into the installer. So, at the very least, you could include a single Property in the library and use that as the link between the library elements and the installer.