24

MS Visual Studio 2013.

Both When and ItemGroup elements can to have the Condition attribute (as I see in MSDN). But I get different results.

When $(CAD_Year) is 2015, I expect the AcRibbon will be not referensed to my project:

<ItemGroup Condition= "'$(CAD_Year)' &lt; '2010'" >    
  <Reference Include="AcRibbon">
    <HintPath>$(CAD_SDK_Location)\$(Inc)\AcRibbon.dll</HintPath>
    <Private>False</Private>
  </Reference>
</ItemGroup>

But I get unresolved reference in the Solution Browser for the AcRibbon always.

But this variant works fine:

<Choose>
  <When Condition= "'$(CAD_Year)' &lt; '2010'">
    <ItemGroup>
      <Reference Include="AcRibbon">
        <HintPath>$(CAD_SDK_Location)\$(Inc)\AcRibbon.dll</HintPath>
        <Private>False</Private>
      </Reference>
    </ItemGroup>
  </When>
</Choose>

At this case the AcRibbon is referenced only when $(CAD_Year) less than 2010. Why I get the different results?

Taylan Aydinli
  • 4,333
  • 15
  • 39
  • 33
Andrey Bushman
  • 11,712
  • 17
  • 87
  • 182
  • Is the ItemGroup in the 1st sample global (defined outside any target)? If so, a possible reason is condition evaluation order. Condition of a global ItemGroup is calculated before any target run. Condition of a local ItemGroup is calculated at parent target run. Global properties are calculated before any ItemGroups and targets. – Nikerboker Mar 04 '15 at 16:18
  • 1
    Are you sure it doesn't work? Visual Studio is not very good at displaying conditional references when you change build configurations, especially if the different build configurations reference things with the same name. The only way to test if it actually works or not is to build it. Sometimes you will get a cross on the Solution Explorer on the dodgy reference - it is safe to leave it alone. – CAD bloke Mar 04 '15 at 22:33
  • Yes, I am sure. This code is located in my external `props`-file. I import its content into my `csproj`-file through the `Import` xml element. – Andrey Bushman Mar 05 '15 at 05:43
  • *unresolved reference in the Solution Browser* that is not exactly relevant as CAD bloke says; does your project build? The code shown works fine. If you add a target which displays @(Reference) then you'll see Reference is empty when CAD_Year is 2015, and contains AcRibbon twice when CAD_Year is e.g. 2008. – stijn Mar 05 '15 at 09:05
  • @CADbloke I agree; the `ItemGroup` Condition does appear to work (VS2019) but the IDE doesn't reflect this if you change build Configuration from Debug to Release, for example. But building either build does result in the correct behaviour in my (recent) experience. – SteveCinq Apr 13 '22 at 22:19

1 Answers1

28

I found the answer in MSDN here:

While conditional import statements work in command-line MSBuilds, they do not work with MSBuild in the Visual Studio integrated development environment (IDE). Conditional imports are evaluated by using the configuration and platform values that are set when the project is loaded. If changes are subsequently made that require a reevaluation of the conditionals in the project file, for example, changing the platform, Visual Studio reevaluates the conditions on properties and items, but not on imports. Because the import conditional is not reevaluated, the import is skipped. To work around this, put conditional imports in the .targets files or put code in a conditional block such as a Choose Element (MSBuild) block.

I think this is true for ItemGroup element also...

Andrey Bushman
  • 11,712
  • 17
  • 87
  • 182
  • Very useful answer. I find it a bit strange that many of the possibilities of MSBuild are not accessible within the IDE. – Codor Dec 11 '15 at 15:36
  • Note: This does not work in Visual Studio for Mac (version 7.5.3) – C.J. Jul 10 '18 at 15:26