开发者

WIX HeatDirectory Task - Setting the preprocessorVariable

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 ha开发者_如何学Gove 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?


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" :)


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>


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>


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.


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>


I have a very large installer kit to build in Visual Studio 2013 (includes some tools related to the main project, a windows service and a web application with a non-trivial directory structure). I'm still learning how to use WiX, and am still crafting, testing and refining the WiX project. Currently, I have the harvest tasks set up as build events, using a command of the form

"C:\Program Files (x86)\WiX Toolset v3.9\bin\heat.exe" dir "$(SolutionDir)\MyProjectDir\bin\$(ConfigurationName)" -cg MyComponentRef -ag -dr MYINSTALLDIR -srd -wixvar -var var.MySourceFiles -sreg -out "$(SolutionDir)\Deployment\My Installer Project\ComponentList.wxs" -t "$(SolutionDir)\Deployment\My Installer Project\FileFilter.xslt"

This command just grabs all the files in the project's bin\Debug (or bin\Release) folder, then filters it using an xml stylesheet transform. There are quite a few harvests to gather like this, so maintaining all the source file variables (the "var.MySourceFiles" argument in the command) was becoming tedious and error prone. Initially, I had added the declarations to the project's preprocessor variables, but I wanted something that was a little more "self-contained". Using the helpful tips I found at WiX tricks and tips, I declared a new include file, "PreprocessorVars.wxi" with content

and got the xslt to include it in the output generated by heat.exe with the snippet

    <xsl:processing-instruction name="include">
        $(sys.CURRENTDIR)\PreprocessorVars.wxi
    </xsl:processing-instruction>

The xslt now produces output that looks something like this:

<?xml version="1.0" encoding="utf-8"?>
    <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:wix="http://schemas.microsoft.com/wix/2006/wi">
        <?include 
                $(sys.CURRENTDIR)\PreprocessorVars.wxi
            ?>
        <Fragment>
            <DirectoryRef Id="MYINSTALLDIR" />
        </Fragment>
        <Fragment>
            <ComponentGroup Id="MyComponentRef">
                <Component Id="xyz" Directory="MYINSTALLDIR" Guid="*">
                    <File Id="abc" KeyPath="yes" Source="$(var.MySourceFiles)\MyProjectExecutable.exe" />
                </Component>
            </ComponentGroup>
        </Fragment>
    </Wix>

which Wix processes without any errors.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜