Search code examples
propertieswixproperties-filewix4

Unable to set a WiX Property equal to a Property from a Properties file


I might be suffering from a case of Sometimers Disease, but I could have sworn the last time I dipped my toe in WiX, it was recommended to have a seperate file for setting properties to be referenced later if any of those properties aren't meant to be static. Basically, updating them before the build sequence begins as-needed.

So basically, I'm trying to:

  1. Load the Properties file into the WiX project (done)
  2. Create a WiX Property equal to one of the properties from that Properties file (blocked)
  3. Reference that value during the sequence of installing as-needed (blocked by blocker, but this can probably help me once #2 is unblocked if I get blocked by #3)

Right now, I'm not able to build due to trying to reference the variable incorrectly with the error, Undefined preprocessor variable '$(var.FOO)'. It builds fine when not trying to. I've tried using sys and env instead of var too. I also tried to use [FOO] but that seems to be treated literally, as when checking the build log, TESTVAR is equal to [FOO] instead of Bar. I don't understand why $(var.FOO) wasn't working. I guess I misunderstood this document.

So I'm not sure what I'm doing wrong, or even how to look for the right way to do it. I've run across some questions that might have led to helpful answers, but they had to do with impossibilities that stunted potential answers, like trying to use the immutable WiX properties once installation starts as mutable.

It's not much more than a default template WiX 4 project, but I've included all my source files below:

vars.properties

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup>
    <FOO>Bar</FOO>
  </PropertyGroup>
</Project>

NewSetupTest.wixproj

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" InitialTargets="EnsureWixToolsetInstalled" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="vars.properties" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
    <ProductVersion>3.9</ProductVersion>
    <ProjectGuid>75fa9a4b-ddfe-44a6-8b03-2f26612b3339</ProjectGuid>
    <SchemaVersion>2.0</SchemaVersion>
    <OutputName>NewSetupTest</OutputName>
    <OutputType>Package</OutputType>
    <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\WiX Toolset\v4\wix.targets</WixTargetsPath>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
    <OutputPath>bin\$(Configuration)\</OutputPath>
    <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
    <DefineConstants>Debug</DefineConstants>
    <VerboseOutput>False</VerboseOutput>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
    <OutputPath>bin\$(Configuration)\</OutputPath>
    <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="Product.wxs" />
  </ItemGroup>
  <ItemGroup>
    <Content Include="vars.properties" />
  </ItemGroup>
  <Import Project="$(WixTargetsPath)" Condition=" Exists('$(WixTargetsPath)') " />
  <Target Name="EnsureWixToolsetInstalled" Condition=" !Exists('$(WixTargetsPath)') ">
    <Error Text="The WiX Toolset v4 build tools must be installed to build this project. To download the WiX Toolset v4, see http://wixtoolset.org/releases/" />
  </Target>
  <!--
    To modify your build process, add your task inside one of the targets below and uncomment it.
    Other similar extension points exist, see Wix.targets.
    <Target Name="BeforeBuild">
    </Target>
    <Target Name="AfterBuild">
    </Target>
    -->
</Project>

Product.wxs

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
    <Product Id="7E5959E4-664D-4D24-9B45-BA2697CA303B"
            Name="NewSetupTest"
            Language="1033"
            Version="1.0.0.3"
            Manufacturer="ACME"
            UpgradeCode="A38ABDBE-2D5F-450D-97EE-19C5A018101B">
        <Package InstallerVersion="200"
              Compressed="yes"
              InstallScope="perMachine" Platform="x64" />

        <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." AllowSameVersionUpgrades="yes"/>
        <MediaTemplate />

        <Feature Id="ProductFeature"
              Title="NewSetupTest"
              Level="1">
            <ComponentGroupRef Id="ProductComponents" />
        </Feature>
    </Product>

    <Fragment>
        <Directory Id="TARGETDIR"
                Name="SourceDir">
            <Directory Id="ProgramFilesFolder64">
                <Directory Id="INSTALLFOLDER"
                    Name="NewSetupTest" />
            </Directory>
        </Directory>
    </Fragment>

    <Fragment>
    <Property Id="TESTVAR" Secure="yes" Value="$(var.FOO)" />
        <ComponentGroup Id="ProductComponents"
                      Directory="INSTALLFOLDER">
            <!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
            <!-- <Component Id="ProductComponent"> -->
                <!-- TODO: Insert files, registry keys, and other resources here. -->
            <!-- </Component> -->
        </ComponentGroup>
    <InstallExecuteSequence>
      <ScheduleReboot After="InstallFinalize">NOT (TESTVAR = "Bar")</ScheduleReboot>
    </InstallExecuteSequence>
    </Fragment>
</Wix>

Solution

  • Besides setting the msbuild properties (you vars.properties), you have to assign Candle preprocessor variables in your .wixproj, under <DefineConstants> as well so that they can be used in you wix projects. This should fix your Undefined preprocessor variable '$(var.FOO)'

    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
        <OutputPath>bin\$(Configuration)\</OutputPath>
        <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
        <DefineConstants>Debug;FOO=$(FOO)</DefineConstants>
        <VerboseOutput>False</VerboseOutput>
    </PropertyGroup>
    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
        <OutputPath>bin\$(Configuration)\</OutputPath>
        <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
        <DefineConstants>FOO=$(FOO)</DefineConstants>
    </PropertyGroup>