WIX HeatDirectory Task - Setting the preprocessorVariable

20,237

Solution 1

PreprocessorVariable for heat really need more doc and example... I've spend lots of time making it work too. This is how it works in my wixproj file:

<PropertyGroup>
  <DefineConstants Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">HarvestPath=..\distribution\Debug</DefineConstants>
  <DefineConstants Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">HarvestPath=..\distribution\Release</DefineConstants>
</PropertyGroup>

<Target Name="BeforeBuild">
  <HeatDirectory Directory="..\distribution\$(Configuration)"
               PreprocessorVariable="var.HarvestPath"
               OutputFile="HeatGeneratedFileList.wxs"
               ComponentGroupName="HeatGenerated"
               DirectoryRefId="INSTALLFOLDER"
               AutogenerateGuids="true"
               ToolPath="$(WixToolPath)"
               SuppressFragments="true"
               SuppressRegistry="true"
               SuppressRootDirectory="true"/>
</Target>

All you need is to define the variable. There is no magical "HeatDefinitions" :)

Solution 2

I use Wix v3.10.

No need to explicitly call HeatDirectory MSBuild Task. ItemGroup with special name "HarvestDirectory" can be prepared, and later the "HarvestDirectory" target will process it. *.wsx file is created in the IntermediateOutputPath and is included in Compile list (processed by Candle).

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
...
  <MyFinalFolder Condition=" '$(MyFinalFolder)' == '' ">$(MSBuildProjectDirectory)\Final\</MyFinalFolder>
  <DefineConstants>FinalFolder=$(MyFinalFolder)</DefineConstants>
</PropertyGroup>

...

<Import Project="$(WixTargetsPath)" />
<Target Name="BeforeBuild">
  <!--
  No need to explicitly call HeatDirectory MSBuild Task.
  Instead follow documentation http://wixtoolset.org/documentation/manual/v3/msbuild/target_reference/harvestdirectory.html, which has sample and 
  important comment:
   This target is processed before compilation. Generated authoring is automatically added to the Compile item group to be compiled by the Candle task.
  So, *.wsx file created in the IntermediateOutputPath and included in Compile list (processed by Candle).

  The following ItemGroup with special name "HarvestDirectory" can be prepared, and later the "HarvestDirectory" target will process it, see
  C:\Program Files (x86)\MSBuild\Microsoft\WiX\v3.x\wix2010.targets
  -->
  <ItemGroup>
    <HarvestDirectory Include="$(MyFinalFolder)">
      <DirectoryRefId>INSTALLFOLDER</DirectoryRefId>
      <SuppressRootDirectory>true</SuppressRootDirectory>
      <SuppressCom>true</SuppressCom>
      <SuppressRegistry>true</SuppressRegistry>
      <ComponentGroupName>FilesComponentGroup</ComponentGroupName>
      <PreprocessorVariable>var.FinalFolder</PreprocessorVariable>
    </HarvestDirectory>
  </ItemGroup>
</Target>

The wxs file:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <DirectoryRef Id="INSTALLFOLDER">
            <Component Id="cmp9AA09F4A73FA53E2BDDE4B7BB5C91DFB" Guid="*">
                <File Id="fil9AA09F4A73FA53E2BDDE4B7BB5C91DFB" KeyPath="yes" Source="$(var.FinalFolder)\7z.dll" />
            </Component>

Solution 3

I created an example project on GitHub showing how to successfully use the HarvestDirectory target, which is a higher-level thing that calls the HeatDirectory task. You don't need to directly call the HeatDirectory task yourself. You can see all of the example code here:

https://github.com/DavidEGrayson/wix-example-harvest-directory

Here are the most important parts:

foo.wixproj

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <ProductVersion>1.0.0</ProductVersion>
    <DefineConstants>ProductVersion=$(ProductVersion);ItemDir=items</DefineConstants>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
    <ProjectGuid>27e80d9b-d8b6-423a-a6ff-1d9c5b23bb31</ProjectGuid>
    <SchemaVersion>2.0</SchemaVersion>
    <OutputName>foo-$(ProductVersion)</OutputName>
    <OutputType>Package</OutputType>
    <DefineSolutionProperties>false</DefineSolutionProperties>
    <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
    <OutputPath>bin\$(Configuration)\</OutputPath>
    <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
    <DefineConstants>Debug;ProductVersion=$(ProductVersion)</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
    <OutputPath>bin\$(Configuration)\</OutputPath>
    <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="foo.wxs" />
    <HarvestDirectory Include="items">
      <DirectoryRefId>ItemDir</DirectoryRefId>
      <ComponentGroupName>Items</ComponentGroupName>
      <PreprocessorVariable>var.ItemDir</PreprocessorVariable>
    </HarvestDirectory>
    <WixExtension Include="WixUIExtension" />
  </ItemGroup>
  <Import Project="$(WixTargetsPath)" />
</Project>

foo.wxs

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Product Name="Foo"
           Version="$(var.ProductVersion)"
           Manufacturer="Foo Inc."
           Language="1033"
           UpgradeCode="0c8504c9-4e62-4e2c-9e1c-4fbe1c478b37"
           Id="*">

    <Package Description="Foo"
             Manufacturer="Foo Inc."
             Compressed="yes"
             InstallerVersion="301" />

    <MajorUpgrade AllowDowngrades="no"
                  DowngradeErrorMessage="A newer version of this software is already installed."
                  AllowSameVersionUpgrades="no" />

    <Media Id="1" Cabinet="cabinet.cab" EmbedCab="yes" />

    <Property Id="ARPCOMMENTS">
      Foo package.
    </Property>
    <Property Id="ARPCONTACT">Foo Inc.</Property>
    <Property Id="ARPURLINFOABOUT">https://www.example.com/</Property>

    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder" Name="PFiles">
        <Directory Id="INSTALLDIR" Name="Foo">
          <Component Id="readme">
            <File Id="readme" Name="README.txt" Source="README.txt" />
          </Component>
          <Directory Id="ItemDir" />
        </Directory>
      </Directory>
    </Directory>

    <Feature Id="Software"
             Title="Foo"
             AllowAdvertise="no"
             ConfigurableDirectory="INSTALLDIR">
      <ComponentRef Id="readme" />
      <ComponentGroupRef Id="Items" />
    </Feature>

    <Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />
    <UIRef Id="WixUI_InstallDir" />
  </Product>
</Wix>

Solution 4

There is a $(HeatDefinitions) property you can set to define these in the parent .wixproj file:

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>  
        <HeatDefinitions>MySourcePath=..\src\Your.App\bin\Release</HeatDefinitions> 
    </PropertyGroup>

    <ItemGroup>
        <Compile Include="Phoenix.wxs" />
        <Compile Include="_HeatGeneratedFileList.wxs" />
    </ItemGroup>

    <Target Name="BeforeBuild">
        <HeatDirectory Directory="..\src\Your.App\bin\Release"
                       OutputFile="_HeatGeneratedFileList.wxs" 
                       PreprocessorVariable="var.MySourcePath" />
    </Target>
</Project>

The only existing mention of this magic property I can find (on the entire Internet) is in a single question about Team Build on the wix-users mailing list. I stumbled across it by luck after spending nearly a day tearing out my hair trying to fix undefined preprocessor variable errors.

Solution 5

I found out what it was, after 1 day of trying various things, the link above is correct but to use the var in the heatdirectory task you have to do it like this.

<HarvestDirectory Include="$(ProjectDirectory)\" >
      <DirectoryRefId>WEBDIR</DirectoryRefId>
      <KeepEmptyDirectories>true</KeepEmptyDirectories>
      <SuppressRegistry>true</SuppressRegistry>
      <ComponentGroupName>DynamicWebFiles</ComponentGroupName>
      <PreprocessorVariable>var.WixDynamicSourceDirectory</PreprocessorVariable>
   </HarvestDirectory>
Share:
20,237
Stuart
Author by

Stuart

Updated on January 01, 2020

Comments

  • Stuart
    Stuart over 4 years

    I'm trying to set the preprocessor variable in wix and i'm unable to find an example of this or explanation on how to do it anywhere on the internet, i'm hoping somebody here can explain or show me where im going wrong!

    I have tried the example shown here regarding setting var values http://www.ageektrapped.com/blog/setting-properties-for-wix-in-msbuild/

    The documentation for using the HeatDirectory taks in wix can be found here and is not very useful at all!

    How do i set the preprocessorVariable to substitute the SourceDir for another variable name?