当定位多个框架时 $(TargetFramework) 为空

Ted*_*erg 6 c# msbuild .net-core

我有一个针对多个框架的项目,在我的文件中使用<TargetFrameworks>(复数).csproj

这工作正常,但我无法执行特定于框架的操作,.csproj因为该$(TargetFramework)属性始终为空。

如果我使用(单一)针对单个框架<TargetFramework>,一切都会按预期工作。

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFrameworks>net5.0;net6.0;net7.0</TargetFrameworks>
    </PropertyGroup>

    <Target Name="DoSomethingFrameworkSpecific" AfterTargets="Build">
        <Message Text="$(TargetFramework)" /><!-- Empty string -->
    </Target>

    <ItemGroup>
        <None Include="MyProject.targets">
            <Pack>True</Pack>
            <PackagePath>build\$(TargetFramework)</PackagePath><!-- File ends up in \build, not build\net5.0 etc -->
        </None>
    </ItemGroup>

</Project>
Run Code Online (Sandbox Code Playgroud)

我的印象是,MSBuild会为每个通道(即每个框架)传递当前框架版本,以便我们可以根据正在构建的版本执行特定于框架的路径或其他条件等操作?

官方文档表明这是可能的: https: //learn.microsoft.com/en-us/dotnet/standard/frameworks#how-to-specify-a-target-framework

SO 的相关问题似乎只处理预处理器指令,而不是在 MSBuild 脚本中获取当前框架版本。

Mik*_*ski 2

如果您需要$(TargetFramework)在针对多个 TFM 时在 nuget pack 路径中使用,请更改<None><TfmSpecificPackageFile>,否则它将无法工作。默认情况下,nuget 将从外部构建而不是特定于 TFM 的构建评估要打包的文件,但如果您使用,<TfmSpecificPackageFile>那么它将重新评估内部 TFM 特定构建的包项。

至于消息 - 我测试了它,它工作得很好,尽管我在外部构建的最后收到一条空消息,加上输出中上面的 TFM 特定消息。如果您想删除空的外部构建消息,只需添加一个条件即可。最终结果应该是这样的:

    <Target Name="DoSomethingFrameworkSpecific" AfterTargets="Build" Condition="'$(TargetFramework)' != ''">
        <Message Text="Message from TFM: $(TargetFramework)" />
    </Target>

    <ItemGroup>
        <TfmSpecificPackageFile Include="MyProject.targets">
            <Pack>True</Pack>
            <PackagePath>build\$(TargetFramework)</PackagePath>
        </TfmSpecificPackageFile>
    </ItemGroup>
Run Code Online (Sandbox Code Playgroud)