NoBrassRing
NoBrassRing

Reputation: 493

In MSBuild, how to propagate a property change to a dependent property?

In MSBuild, I am trying to dynamically generate a property, one that is dependent on the value of another property. This seems related to but not identical with How get exec task output with msbuild and Dynamically create a property in msbuild to be used in a calltarget subtarget

Please see the sample below. It is trying generate property WixVariable, which is dependent on property MsiVersion. (FYI, Though it is not really relevant to this problem, this code relates to preparing WixVariables, which is passed to wix.exe to generate a MS installer.)

At (1) property MsiVersion is assigned the value "unknown"

At (2) property WixVariables is assigned the value "MSI_VERSION=unknown;OTHER_VARIABLE=OtherValue"

At (3) a powershell script is run to generate the actual version number. To keep the sample simple, it just returns "4.3".

At (4) property MsiVersion is supposed to be assigned the new value "4.3"

And this should update property WixVariables to have the value "MSI_VERSION=4.3;OTHER_VARIABLE=OtherValue"

But that doesn't work. WixVariables remains unchanged.

I've been experimenting with this for several hours but cannot get the result I need: WixVariables to reflect the generated value of MsiVersion.

        <?xml version="1.0" encoding="utf-8"?>
        <Project ToolsVersion="4.0" DefaultTargets="Build" InitialTargets="EnsureWixToolsetInstalled" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

          <PropertyGroup>
            <AProperty>SomeValue</AProperty>
(1)         <MsiVersion>unknown</MsiVersion>
          </PropertyGroup>

          <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
            ... snip
(2)         <WixVariables>MSI_VERSION=$(MsiVersion);OTHER_VARIABLE=OtherValue</WixVariables>
          </PropertyGroup>

          <Target Name="BeforeBuild" />
(3)         <Exec ConsoleToMSBuild="true" Command="powershell -NoProfile -ExecutionPolicy ByPass -Command &quot; Write-Output 4.3 &quot;">
(4)           <Output TaskParameter="ConsoleOutput" PropertyName="MsiVersion" />
            </Exec> 
          </Target>

        </Project>

Upvotes: 2

Views: 638

Answers (1)

NoBrassRing
NoBrassRing

Reputation: 493

Ok, after much experimenting I have an answer to my question and a better understanding of MSBuild.

What I did not understand is that once a property is assigned a value [see (1) and (2) in the sample above) the property's value is fixed.

The code at (4) does update the value of MsiVersion but not update the value of WixVariables. In other words the line at (2) is NOT re-evaluated when property MsiVersion changes.

To update the value of WixVariables, it must be set explicitly as the code below at (5) does.

A working sample is shown below. Unlike the question sample, there is no point in initially creating MsiVersion=unknown or prepending WixVariables with "MSI_VERSION=unknown".

        <?xml version="1.0" encoding="utf-8"?>
        <Project ToolsVersion="4.0" DefaultTargets="Build" InitialTargets="EnsureWixToolsetInstalled" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

          <PropertyGroup>
            <AProperty>SomeValue</AProperty>
          </PropertyGroup>

          <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
            ... snip
            <WixVariables>OTHER_VARIABLE=OtherValue</WixVariables>
          </PropertyGroup>

          <Target Name="BeforeBuild" />
            <Exec ConsoleToMSBuild="true" Command="powershell -NoProfile -ExecutionPolicy ByPass -Command &quot; Write-Output 4.3 &quot;">
              <Output TaskParameter="ConsoleOutput" PropertyName="MsiVersion" />
            </Exec> 
(5)         <CreateProperty Value="MSI_VERSION=$(MsiVersion);$(WixVariables)">
                <Output TaskParameter="Value" PropertyName="WixVariables" />
            </CreateProperty>
          </Target>

        </Project>

Upvotes: 3

Related Questions