wixwix3.5heat

Harvesting multiple directories in WiX


I'm trying to build an installer that includes a number of features and I'm using heat to harvest a directory of files for each feature.
My source directory structure looks something like this:

HarvestDir
          \FeatureA
                   \FeatureImpl.dll
                   \FeatureImpl2.dll
          \FeatureB
                   \FeatureImpl.dll
                   \FeatureImpl2.dll

So I execute heat.exe for each feature to create a fragment for each feature but I get basically identical fragments e.g.

[...] Source="SourceDir\FeatureImpl.dll"
[...] Source="SourceDir\FeatureImpl2.dll"

What I really want is something like this:

[...] Source="SourceDir\FeatureA\FeatureImpl.dll"
[...] Source="SourceDir\FeatureA\FeatureImpl2.dll"

and

[...] Source="SourceDir\FeatureB\FeatureImpl.dll"
[...] Source="SourceDir\FeatureB\FeatureImpl2.dll"

I could use -var to specify a separate variable to represent the source location for each feature, but then I'd have to pass values for these variables into the wixproj (and I'm going to have ~10 features).

So, is there any way I can include a relative path in my harvested fragment?


Solution

  • You can either assign your source paths in .wixproj in DefineConstants or you can assign them in a WIX include file but either way you will have to use "var" option to specify the variable being used for your sources.

    If you want to use DefineConstant in wixproj then you will have to do something like

            <Target Name="BeforeBuild">
                <PropertyGroup>
                  <DefineConstants>BINFOLDER=..\PATH\TO\SOURCE\$(Configuration)</DefineConstants>
                </PropertyGroup>    
                <HeatDirectory OutputFile="output.wxs" Directory="..\PATH\TO\SOURCE\$(Configuration)" DirectoryRefId="INSTALLFOLDER" ComponentGroupName="COMPONENTGROUPNAME" ToolPath="$(WixToolPath)" PreprocessorVariable="var.BINFOLDER" />    
            </Target>
    

    In Heat task make sure you add any additional attributes that you might need. In case you have added a reference to your source project in the .wixproj then you may directly use the project reference variables in the "PreprocessorVariable" attribute. For example instead of var.BINFOLDER use var.MyProject.TargetDir.

    If you want to use a WIX include file (.wxi) then declare your variables in an include file for example Variables.wxi:

            <?xml version="1.0" encoding="UTF-8"?>
            <Include>
              <?define PATH1="PATH\TO\SOURCE"?>
              <?define PATH2="$(var.PATH1)\$(Configuration)"?>
            </Include>
    

    Now you will need to pass in PATH1 and PATH2 using the -var in the heat command line. Once you have your .wxs file you will then need to include the Variables.wxi file in that using

    <?include Variables.wxi ?>
    

    in your .wxs. The problem with this way is that you will have to either add this include directive manually each time you generate your WIX source files or you will have to inject it using XSL Transformation.