From MSI to WiX, Part 16 - Installable Items - Handling Installation Media

The main page for the series is here.

 

Introduction

Before we start talking about installing files, I feel that we need to understand the options we have in distributing files that need to be installed with our installation package.

The following elements are involved in the distributing source files with the installation package on the MSI side:

On the WiX side:

Following sections describe available options in file distribution.

Uncompressed files distributed along with the installation package

Consider the following sample:

<?xml version="1.0" encoding="UTF-8"?>

<Wix xmlns="https://schemas.microsoft.com/wix/2003/01/wi">

  <Product Id="{E2842676-5648-4A17-8993-E4BA183AAB55}"

           Name="Minimal Windows Installer Sample"

           Language="1033"

           Codepage="1252"

           Version="1.0.0"

           Manufacturer="Acme Corporation"

           UpgradeCode="{57068987-D43F-4B69-AD33-0B2CB755F6FB}">

    <Package Id="{????????-????-????-????-????????????}"

             Description="Minimal Windows Installer Sample"

             Comments="This installer database."

             InstallerVersion="200"

             Languages="1033"

             SummaryCodepage="1252"

             Platforms="Intel"

             ReadOnly="no"

             Compressed="no"

             AdminImage="no"

             Keywords="Installer"

             ShortNames ="no"

             Manufacturer="Acme Corporation" />

    <Media Id="1" Cabinet="CAB001.cab" />

    <Directory Id="TARGETDIR" Name="SourceDir">

      <Directory Id="ProgramFilesFolder">

        <Directory Id="INSTALLLOCATION"

                  Name="Minimal"

                  LongName="MinimalInstallation">

          <Component Id="Component1"

                     Guid="{73440E8A-D60D-4600-A4EF-F9716D1D2AD8}">

            <File Id="ReadMe" DiskId="1"

                 Name="Readme.txt" Source="Readme.txt"

                  Vital="yes" KeyPath="yes" />

            <File Id="ReadMe2" DiskId="1"

                 Name="Readme2.txt" Source="Readme2.txt"

                  Vital="yes" />

          </Component>

        </Directory>

      </Directory>

    </Directory>

    <Feature Id="Feature1"

             Level="1">

      <ComponentRef Id="Component1" />

    </Feature>

  </Product>

</Wix>

Attribute Compressed of the <Package> element defines on the package level if files in the installation package will be distributed uncompressed or will be packaged in the CAB files.  In our sample this attribute is set to "no" which means files by default will not be packaged in the CAB files.

If you will compile the sample code (attached to this blog as V1.zip), you'll notice that in addition to Minimal.msi compiler will create a MinimalInstallation folder with Readme.txt and Readme2.txt files.  They are required because MSI file does not contain these two files, only references to them.  If you want to ship this sample to your customers, you must ship Minimal.msi and folder MinimalInstallation with Readme.txt and Readme2.txt files in it.

Mix of uncompressed and compressed files

We can override package level compression settings (Package/@Compressed) on the file level using Compressed attribute of the <File> element:

<?xml version="1.0" encoding="UTF-8"?>

<Wix xmlns="https://schemas.microsoft.com/wix/2003/01/wi">

  <Product Id="{E2842676-5648-4A17-8993-E4BA183AAB55}"

           Name="Minimal Windows Installer Sample"

           Language="1033"

           Codepage="1252"

           Version="1.0.0"

           Manufacturer="Acme Corporation"

           UpgradeCode="{57068987-D43F-4B69-AD33-0B2CB755F6FB}">

    <Package Id="{????????-????-????-????-????????????}"

             Description="Minimal Windows Installer Sample"

             Comments="This installer database."

             InstallerVersion="200"

             Languages="1033"

             SummaryCodepage="1252"

             Platforms="Intel"

             ReadOnly="no"

             Compressed="no"

             AdminImage="no"

             Keywords="Installer"

             ShortNames ="no"

             Manufacturer="Acme Corporation" />

    <Media Id="1" Cabinet="CAB001.cab" />

    <Directory Id="TARGETDIR" Name="SourceDir">

      <Directory Id="ProgramFilesFolder">

        <Directory Id="INSTALLLOCATION"

                  Name="Minimal"

                  LongName="MinimalInstallation">

          <Component Id="Component1"

                     Guid="{73440E8A-D60D-4600-A4EF-F9716D1D2AD8}">

            <File Id="ReadMe" DiskId="1"

                  Name="Readme.txt" Source="Readme.txt"

                  Vital="yes" KeyPath="yes" />

            <File Id="ReadMe2" DiskId="1"

                  Name="Readme2.txt" Source="Readme2.txt"

                  Vital="yes"

                  Compressed="yes" />

          </Component>

        </Directory>

      </Directory>

    </Directory>

    <Feature Id="Feature1"

             Level="1">

      <ComponentRef Id="Component1" />

    </Feature>

  </Product>

</Wix>

Notice that <File> element with Id attribute set to Readme2 has additional attribute Compressed set to "yes".  Now after compiling project we will get an MSI file, CAB001.cab file, and folder MinimalInstallation with Readme.txt file in it.

All source files are compressed

If we want all files to be compressed we can set Package/@Compressed attribute to "yes".  Also, because CAB file can hold no more than 32767 files, we can pack source files in more than one CAB file:

<?xml version="1.0" encoding="UTF-8"?>

<Wix xmlns="https://schemas.microsoft.com/wix/2003/01/wi">

  <Product Id="{E2842676-5648-4A17-8993-E4BA183AAB55}"

           Name="Minimal Windows Installer Sample"

           Language="1033"

           Codepage="1252"

           Version="1.0.0"

           Manufacturer="Acme Corporation"

           UpgradeCode="{57068987-D43F-4B69-AD33-0B2CB755F6FB}">

    <Package Id="{????????-????-????-????-????????????}"

             Description="Minimal Windows Installer Sample"

             Comments="This installer database."

             InstallerVersion="200"

             Languages="1033"

             SummaryCodepage="1252"

             Platforms="Intel"

             ReadOnly="no"

             Compressed="yes"

             AdminImage="no"

           Keywords="Installer"

             ShortNames ="no"

             Manufacturer="Acme Corporation" />

    <Media Id="1" Cabinet="CAB001.cab" />

    <Media Id="2" Cabinet="CAB002.cab" />

    <Directory Id="TARGETDIR" Name="SourceDir">

      <Directory Id="ProgramFilesFolder">

        <Directory Id="INSTALLLOCATION"

                   Name="Minimal"

                   LongName="MinimalInstallation">

          <Component Id="Component1"

                     Guid="{73440E8A-D60D-4600-A4EF-F9716D1D2AD8}">

            <File Id="ReadMe" DiskId="1"

                  Name="Readme.txt" Source="Readme.txt"

                  Vital="yes" KeyPath="yes" />

            <File Id="ReadMe2" DiskId="2"

                  Name="Readme2.txt" Source="Readme2.txt"

                  Vital="yes" />

          </Component>

        </Directory>

      </Directory>

    </Directory>

    <Feature Id="Feature1"

             Level="1">

      <ComponentRef Id="Component1" />

    </Feature>

  </Product>

</Wix>

Source files are compressed and CAB files are embedded in MSI file

You can embed a CAB file in installation package by setting EmbedCab attribute of <Media> element to "yes".  Also, by setting the value of CompressionLevel attribute of <Media> element you can change, you guessed it, compression level:

<?xml version="1.0" encoding="UTF-8"?>

<Wix xmlns="https://schemas.microsoft.com/wix/2003/01/wi">

  <Product Id="{E2842676-5648-4A17-8993-E4BA183AAB55}"

           Name="Minimal Windows Installer Sample"

           Language="1033"

           Codepage="1252"

           Version="1.0.0"

           Manufacturer="Acme Corporation"

           UpgradeCode="{57068987-D43F-4B69-AD33-0B2CB755F6FB}">

    <Package Id="{????????-????-????-????-????????????}"

             Description="Minimal Windows Installer Sample"

             Comments="This installer database."

             InstallerVersion="200"

             Languages="1033"

             SummaryCodepage="1252"

             Platforms="Intel"

             ReadOnly="no"

             Compressed="yes"

             AdminImage="no"

  Keywords="Installer"

             ShortNames ="no"

             Manufacturer="Acme Corporation" />

    <Media Id="1" Cabinet="CAB001.cab"

          EmbedCab="yes" CompressionLevel="high" />

    <Directory Id="TARGETDIR" Name="SourceDir">

      <Directory Id="ProgramFilesFolder">

        <Directory Id="INSTALLLOCATION"

                   Name="Minimal"

                   LongName="MinimalInstallation">

          <Component Id="Component1"

                     Guid="{73440E8A-D60D-4600-A4EF-F9716D1D2AD8}">

            <File Id="ReadMe" DiskId="1"

                  Name="Readme.txt" Source="Readme.txt"

                  Vital="yes" KeyPath="yes" />

            <File Id="ReadMe2" DiskId="1"

                  Name="Readme2.txt" Source="Readme2.txt"

                  Vital="yes" />

          </Component>

        </Directory>

      </Directory>

    </Directory>

    <Feature Id="Feature1"

             Level="1">

      <ComponentRef Id="Component1" />

    </Feature>

  </Product>

</Wix>

Installing from removable media

If you ship your product on removable media, such as floppy disks, CD's or DVD's, you want to add disk prompt message support to your installation package.  The whole process is described here, but it boils down to this:

  • Add a message which will be displayed to the users when they will need to change the media.  This is done by authoring error message with Id=1302 (Look for <UI> and <Error> elements in the sample below).
  • Add DiskPrompt property which holds the name of your application and is a part of the message shown to the user.  This message is a substitution for parameter [2] in the error 1302 message.
  • Add DiskPrompt and VolumeLabel attributes to the <Media> element.  DiskPrompt contains the name of the media and is substitution for parameter [1] in DiskPrompt property's message.  VolumeLabel must be set to the Volume Label name of the media which will have the corresponding CAB file.

Here is the full source code for the sample:

<?xml version="1.0" encoding="UTF-8"?>

<Wix xmlns="https://schemas.microsoft.com/wix/2003/01/wi">

  <Product Id="{E2842676-5648-4A17-8993-E4BA183AAB55}"

           Name="Minimal Windows Installer Sample"

           Language="1033"

           Codepage="1252"

           Version="1.0.0"

           Manufacturer="Acme Corporation"

           UpgradeCode="{57068987-D43F-4B69-AD33-0B2CB755F6FB}">

    <Package Id="{????????-????-????-????-????????????}"

             Description="Minimal Windows Installer Sample"

             Comments="This installer database."

             InstallerVersion="200"

             Languages="1033"

             SummaryCodepage="1252"

             Platforms="Intel"

             ReadOnly="no"

             Compressed="yes"

             AdminImage="no"

             Keywords="Installer"

             ShortNames ="no"

             Manufacturer="Acme Corporation" />

    <UI>

      <Error Id="1302">Hey, please insert [2]!</Error>

    </UI>

    <Property Id="DiskPrompt" Value="Minimal Installation - [1]" />

    <Media Id="1" Cabinet="CAB001.cab"

           DiskPrompt="Disk 1" VolumeLabel="Disk1" />

    <Media Id="2" Cabinet="CAB002.cab"

           DiskPrompt="Disk 2" VolumeLabel="Disk2" />

    <Directory Id="TARGETDIR" Name="SourceDir">

      <Directory Id="ProgramFilesFolder">

        <Directory Id="INSTALLLOCATION"

                  Name="Minimal"

                  LongName="MinimalInstallation">

          <Component Id="Component1"

                     Guid="{73440E8A-D60D-4600-A4EF-F9716D1D2AD8}">

            <File Id="ReadMe" DiskId="1"

                  Name="Readme.txt" Source="Readme.txt"

                  Vital="yes" KeyPath="yes" />

            <File Id="ReadMe2" DiskId="2"

                  Name="Readme2.txt" Source="Readme2.txt"

                  Vital="yes" />

          </Component>

        </Directory>

      </Directory>

    </Directory>

    <Feature Id="Feature1"

             Level="1">

      <ComponentRef Id="Component1" />

    </Feature>

  </Product>

</Wix>

 

V1.zip