Ok there is this hidden feature of MSBuild its called output inferral. This is used when a target is skipped due its Inputs & Outputs (incremental building) but the target creates properties and items. Eventhough the inputs and outputs are up to date the side effects (properties & items) may change the rest of the build process. Because of this output inferral is required. When a target is skipped MSBuild will inspect the target for properties & items that were created and create those. This will ensure that other targets down the chain will not be affected by the target being skipped. In MSBuild 3.5 there is a new property on the CreateProperty task, this property is ValueSetByTask. The whole purpose of this is to only be used when you do not want its value to be inferred. By using this property instead of Value you would be guaranteed that the target was actually executed. Let's clear this up with an example take a look at the project file shown below.
This target will always be skipped .
Neither property One or Two exists but One will be inferred
<Message Text="SetuptValues Executed!" Importance="high"/>
<Output PropertyName="One" TaskParameter="Value"/>
<!-- Property One is actually inferred by this statement. -->
<Output PropertyName="Two" TaskParameter="ValueSetByTask"/>
<!-- Using ValueSetByTask we can ensure bypassing any inferring here -->
<!-- 3.5 syntax: Property Three is also inferred -->
<!-- Items are inferred too! -->
<Target Name="PrintValues" DependsOnTargets="SetupValues">
<Message Text="One: $(One)" />
<Message Text="Two: $(Two)" />
<Message Text="Three: $(Three)"/>
<Message Text="File: @(File)"/>
In this file (you can download from link at end) there are two targets, SetupValues and PrintValues. PrintValues depends on SetupValues. Because the Inputs and Outputs on SetupValues point to the same file the target will always be skipped. But we declare properties and items so they have to be inferred by the MSBuidl engine so that the remainder of the build will not be hosed because of it. If you execute the PrintValues target the result would be what you see in the image below.
As you can see the values for the properties One & Three were provided by inference but the value for Two was passed over because it uses the ValueSetByTask instead of Value. I would suggest that you continue to use the Value property and not the ValueSetByTask unless you are trying to detect this exact scenario, which most of the time shouldn't matter anywayz.
Sayed Ibrahim Hashimi