MSBuild如何检测.NET Core的版本?

5
在MSBuild项目文件中 (例如,*.csproj),我可以通过检查MSBuildRuntimeType属性: '$(MSBuildRuntimeType)'!='Core' 来检测它是否使用.NET Core或.NET Framework或Mono。同样的方式,我能否检测它是哪个版本的.NET Core (例如2.1、2.2、3.0、3.1)呢?

MsBuild的MSBuildRuntimeType与任何.NET Core“检测”都不对应。它只是意味着您基本上正在运行.NET Core的MsBuild,或者另一个(“Mono”,“Full”)。请参见此处的MsBuild源代码:https://github.com/microsoft/msbuild/blob/fa773bb8d44a358963481c02e772509dc408a6d9/src/Build/Evaluation/Evaluator.cs#L1140,它是硬编码的,取决于您如何编译MsBuild。您是否正在寻找目标框架/平台属性:https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-target-framework-and-target-platform?view=vs-2019? - Simon Mourier
2个回答

8
你可以这样获取它:
System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription.ToString();

这将返回类似于以下的版本。

.NET Core 3.1.0

您可以像这样在MSBuild中分配属性:
<MSBuildRuntimeVersion>$([System.Runtime.InteropServices.RuntimeInformation]:: FrameworkDescription.ToString())</MSBuildRuntimeVersion>

更新:

根据 @minhee 的评论,我了解到上述解决方案在 .NET Core 2.2 或更早版本上不起作用。我对此进行了一些研究,并发现这是 CoreFx 中的一个重大变化,即报告版本的 API 现在报告产品而不是文件版本。

这个新特性是在 .NET Core 3.0 引入的,因为我没有使用 .NET Core 2.2 或更早的版本,所以我不知道这一点。

话虽如此,我想提出另一个解决方案,它适用于所有版本的 .NET Core。

Assembly.GetEntryAssembly().GetCustomAttribute<TargetFrameworkAttribute>().FrameworkName;

在这里,您将获得以下版本号。

.NETCoreApp,Version=v3.0

我已经在控制台应用程序中测试了这段代码,下面是我测试时使用的相关版本。

.NET Core 2.0
.NET Core 2.1
.NET Core 2.2
.NET Core 3.0
.NET Core 3.1

在MSBuild中:

您也可以在MSBuild中检查相同的内容。

例如,在下面的.csproj文件中,我根据目标框架的条件定义了两个消息任务。因此,如果我使用目标框架作为netcoreapp2.2构建项目,则它将在构建日志中打印“Happy 2020…”;如果我使用目标框架作为netcoreapp3.0构建项目,则它将在构建日志中打印“Happy New Year…”

<Project Sdk="Microsoft.NET.Sdk">
    <Target Name="FooName" BeforeTargets="Build" Condition="'$(TargetFrameworkVersion)'=='v3.0'">
        <Message Text="Happy New Year..." Importance="High" />
    </Target>
    <Target Name="FooName" BeforeTargets="Build" Condition="'$(TargetFrameworkVersion)'=='v2.2'">
        <Message Text="Happy 2020..." Importance="High" />
    </Target>
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp2.2</TargetFramework>
        <RootNamespace>New_folder</RootNamespace>
    </PropertyGroup>
</Project>

因此,您可以使用TargetFrameworkVersion属性来检测MSBuild中.NET Core的当前版本。

希望这能帮到您。


在.NET Core 2.2上,它似乎返回了一个不正确的版本字符串:.NET Core 4.6.28207.03 - minhee
不幸的是,这会导致MSB4185错误,因为Assembly.GetEntryAssembly()方法似乎未包含在MSBuild的安全函数列表中。 - minhee
为什么你只想用Reflection来做,而不选择使用MSBuild条件呢? - Keyur Ramoliya
你能详细说明一下使用MSBuild条件选项的情况吗? - minhee
我在谈论 .csproj 中的 Condition="'$(TargetFrameworkVersion)'=='v3.0'"。不采用这种方法是否有特定原因? - Keyur Ramoliya
显示剩余2条评论

0

你也可以尝试使用 $([System.Environment]::Version),例如:

<Message Importance="High" Text="$([System.Environment]::Version)" />
<Message Importance="High" Text="$([System.Environment]::Version.Major)" />

适用于NetFramework和Net6(这是我本地可用的版本)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接