WIX Heat Wave Brings Changes

There has been some recent work to Heat.exe, within the Windows Installer XML Toolset (WiX), which I think will have a significant impact on how people use the application currently and how it will be used in the feature. The features are brought forth from a great deal of user feedback and a general need for some “tender, loving care.” People have been using Heat to harvest various data stores and including the auto-generated .wxs files as part of their projects. This has been a good “start” for many projects but the intent was not to use it for constant re-generation in a build environment for dynamic content.

Although this practice is still recommend against, this last update is a set in the direction of consistent regeneration. In Windows Installer this is a very difficult task to manage as there are many rules that a package must confirm to in order to be patch compliant. Not only must Component GUIDs remain stable, the File ID, Registry ID, Directory ID Media Number and other items must stay consistent. If this does not happen there can be serious implications to the “in-place” servicing of your product.

Several years ago I was working on a way to do what heat.exe is starting to do now, auto-generate dynamic content in a compliant way. My project, WIXML, failed to generate MSIs that were upgrade compliant. It was necessary to do a full uninstall with each new package because it broke all the rules that I mentioned above (additional information from Bob Arnson “Paying for Upgrades”). With the latest update, Heat is getting closer to the ability of being compliant with consistent re-generation.

There has been four significant command line switches added that will help users comply to the rules above.

-cg <GroupName>
-dr <DirectoryRefId>
-srd
-var

The –cg <GroupName> command instructs Heat to harvest a given directory and include all found components in a <ComponentGroup/> with the given name. This will ensure that, when authoring a full product, a developer can be guaranteed a static value to reference using a <CompnentGroupRef/>.

 heat.exe dir C:\MyDir -srd -cg TestMe


<Wix xmlns="https://schemas.microsoft.com/wix/2006/wi">
  <Fragment>
    <ComponentGroup Id="TestMe">
      <Component Id="CO_BEA0A254206A075FE419AECC8F8323C3" Directory="DI_5E971BF1ECC0BC11795785D90F250FC0" ... >
        <File Id="FI_4273BB2732377498E74980308130C808" ... />
      </Component>

The -dr switch takes a value of a DirectoryRef/@Id. This will become the directory which all other directories are rooted under.

In addition, and important to note, this acts as the seed for all the identifier generation.

Changing this value will directly impact the values of ALL the identifiers. When this value is not specified, it will default to "TARGETDIR".

 heat.exe dir C:\MyDir -srd -dr MyDir


<Wix xmlns="https://schemas.microsoft.com/wix/2006/wi">
  <DirectoryRef Id="MyDir">
    <Component Id="CO_BEA0A254206A075FE419AECC8F8323C3" Directory="DI_5E971BF1ECC0BC11795785D90F250FC0" ... >
      <File Id="FI_4273BB2732377498E74980308130C808" ... />
    </Component>

The -srd switch suppresses the including the root directory of the path given. Using this switch will also change the values of identifiers being generated because of how they will be rooted.

Change this switch with high caution and review on the impact to your product.

 heat.exe dir C:\MyDir -sfrag


<Wix xmlns="https://schemas.microsoft.com/wix/2006/wi">
  <Fragment>
    <DirectoryRef Id="TARGETDIR">
      <Directory Id="dir86787CC870C17D6ABA6D1CDCBD925324" Name="MyDir">
        <Directory Id="dirAA5EBADF0D0CC654BAD8E2CEFBF96609" Name="one">
          <Component Id="cmp51B22E187A7403EF3A8EB589174E89DC" ...>
            <File Id="filEA449989D4339EB8C7329B93F83D35FE" ... />
          </Component>
        </Directory>

heat.exe dir C:\MyDir -srd -sfrag


<Wix xmlns="https://schemas.microsoft.com/wix/2006/wi">
  <Fragment>
    <DirectoryRef Id="TARGETDIR">
      <Directory Id="dir090ACB8E8D9B8C1F26DE6E8300AA9049" Name="one">
        <Component Id="cmpE21824A6879A478E4A884BA6B00C33C9" ...>
          <File Id="filF1BA1271365EB2A130AA3F0BE83E9D6D" ... />
        </Component>
    </Directory>

The -var switch value of the preprocessor variable you want to use "$(<var|env>.MyVar)". Renaming this value will not impact dynamically created identifiers.

 heat.exe dir C:\MyDir -srd -sfrag -var var.MyVar


<Wix xmlns="https://schemas.microsoft.com/wix/2006/wi">
<Fragment>
  <DirectoryRef Id="TARGETDIR">
    <Directory Id="dir090ACB8E8D9B8C1F26DE6E8300AA9049" Name="one">
      <Component Id="cmpE21824A6879A478E4A884BA6B00C33C9" ...>
        <File Id="filF1BA1271365EB2A130AA3F0BE83E9D6D" Source="$(var.MyVar)\one\test.txt" ... />
      </Component>
    </Directory>

As always, feedback is appreciated! I hope these changes help some people onboard!

Comments

  • Anonymous
    September 08, 2009
    The comment has been removed

  • Anonymous
    September 09, 2009
    @Mladen It is true that you can harvest the registry information from a .NET COM .DLL. Just run "heat.exe file {filename.ext} -out mycom.wxs" If you don't use -sreg or other switches heat.exe will try to harvest infromation from all .dll files.

  • Anonymous
    September 11, 2009
    @brian6p i've used heat and it output a nice xml but it won't compile and it gives me this error: The Class element's ForeignServer or Server attribute was not found; one of these is required. which one should i set and to what? the class xml is <Class Id="{5757DC92-D926-4684-9CB5-B42054A90E53}" Context="InprocServer32" Description="l" ThreadingModel="both"> <ProgId Id="MyId" Description="MyDescription" /> </Class>

  • Anonymous
    September 11, 2009
    @Mladen It sounds like you are using a .NET COM DLL. It almost sounds like it isn't authored correctly if the ForeignServer isn't already populated with mscoree.dll. You should move the converstation over to the wix-users forum @ http://sourceforge.net/projects/wix/support. You will have a bigger support group there <grin/>

  • Anonymous
    September 08, 2016
    Hi,Please let me know if we can create a .wxs file with both file and reg harvest type together.I would like to auto-generate a .wxs file using single heat.exe command that looks something like this :