.netmsbuild

Target all .Net versions of .net5 or higher in msbuild condition


When building a application with multiple target Frameworks .Net 6.0 and .Net Framework 4.7.2 (<TargetFrameworks>net6.0;net472</TargetFrameworks>) application you can specify conditions for msbuild in a project or target file like that:

<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'"> Something </ItemGroup>
OR
<Target Name="MyUniqueTarget213243" BeforeTargets="Build">
    <Message Importance="high" Text="Message for .net Framework" Condition="$(TargetFramework)' == 'net472'" />
    <Message Importance="high" Text="Message for .net 6 and higher" Condition="$(TargetFramework)' == 'net6.0'" />
</Target>

This works good for the specific versions of .net Framework 4.7.2 and .Net 6.0, but it'll break for .net 8 or .net Framework 3.5.

As the old framework will always be net472, that's no problem, but the newer one will be updated anytime to 8.0 or 10.0 or whatever.

Can I set a condition to target all versions of .Net 5 and above (like net5.0, net6.0, net8.0 or net8.3)[If there will ever be 8.3], but not .net core(netcoreapp2.1) or .net Framework 4.7.2(net472)

What I tried so far:

<Message Importance="high" Text="Output Substring+Trim: '$(TargetFramework.Substring(3).Trim(`1234567890`))'" />
<Message Condition="'$(TargetFramework.Substring(3).Trim(`1234567890`))' == '.'" Importance="high" Text="ShowsIfConditionIsTrue" />
<!---> error MSB4184: The expression """.Substring(3)" cannot be evaluated. startIndex cannot be larger than length of string. Msbuild seems to do a build where TargetFramework is ''-->
<!---> Can be paired with condition like '$(TargetFramework)' != '', but complicated and seems stupid-->
<Message Importance="high" Text="Output Trim: '$(TargetFramework.Trim(`net1234567890`))'" />
<Message Condition="'$(TargetFramework.Trim(`net1234567890`))' == '.'" Importance="high" Text="ShowsIfConditionIsTrue" />
<!---> unreliable-->
<Message Condition="'$(TargetFramework.Contains(`net6`))' == true" Importance="high" Text="ShowsIfConditionIsTrue" />
<!---> checks only one framework-->
<Message Condition="'$(new string[]{`net5.0`, `net6.0`}.Contains(TargetFramework))' == true" Importance="high" Text="ShowsIfConditionIsTrue" />
<!---> error: new string[]{`net5.0`, `net6.0`}.Contains(TargetFramework) cannot be evaluated-->
<!--  -> only fixed values-->
<Message Condition="'$(TargetFramework)' != 'net472'" Importance="high" Text="ShowsIfConditionIsTrue" />
<!---> may target net45 or netcoreSomething or whatever-->

Solution

  • Based on the comment of Xenohon, how about something like this:

    <PropertyGroup>
        <IsUnifiedNETVersion>$([MSBuild]::VersionGreaterThanOrEquals('$([MSBuild]::GetTargetFrameworkVersion('$(TargetFramework)'))','6.0'))</IsUnifiedNETVersion>
        <MessageText Condition="$(IsUnifiedNETVersion) == 'true'">NET 6 or Higher is beeing used</MessageText>
        <MessageText Condition="$(IsUnifiedNETVersion) == 'false'">NET472 is beeing used</MessageText>
    </PropertyGroup>
    
    <Target Name="MyTarget" AfterTargets="AfterBuild">
        <Message Importance="High" Text="IsNet6OrHigher = $(IsUnifiedNETVersion)" />
        <Message Importance="High" Text="$(MessageText)" />
    </Target>