编译时检测.NET Framework框架版本
2024-03-17 17:33:41

在新的.NET框架下,官方自带了一些用于判断框架版本的条件变量(C#预处理器指令

但是在老的编译系统上没有此功能,所以只能模拟实现。

终于在 stackoverflow 上找到了答案,思路很不错,在.csproj工程文件中利用框架的System.Version去动态比较版本号,然后定义相关的条件变量。

解决方案

在原答案的基础上修改了一下,兼容了微软官方的条件变量。

创建一个新文件FrameworkSymbols.Common.prop,内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<DefineConstants Condition="$([System.Version]::Parse('$(TargetFrameworkVersion.Substring(1))').CompareTo($([System.Version]::Parse('4.8')))) &gt;= 0">$(DefineConstants);NET48;NET48_OR_GREATER</DefineConstants>
<DefineConstants Condition="$([System.Version]::Parse('$(TargetFrameworkVersion.Substring(1))').CompareTo($([System.Version]::Parse('4.7.2')))) &gt;= 0">$(DefineConstants);NET472;NET472_OR_GREATER</DefineConstants>
<DefineConstants Condition="$([System.Version]::Parse('$(TargetFrameworkVersion.Substring(1))').CompareTo($([System.Version]::Parse('4.7.1')))) &gt;= 0">$(DefineConstants);NET471;NET471_OR_GREATER</DefineConstants>
<DefineConstants Condition="$([System.Version]::Parse('$(TargetFrameworkVersion.Substring(1))').CompareTo($([System.Version]::Parse('4.7')))) &gt;= 0">$(DefineConstants);NET47;NET47_OR_GREATER</DefineConstants>
<DefineConstants Condition="$([System.Version]::Parse('$(TargetFrameworkVersion.Substring(1))').CompareTo($([System.Version]::Parse('4.6.2')))) &gt;= 0">$(DefineConstants);NET462;NET462_OR_GREATER</DefineConstants>
<DefineConstants Condition="$([System.Version]::Parse('$(TargetFrameworkVersion.Substring(1))').CompareTo($([System.Version]::Parse('4.6.1')))) &gt;= 0">$(DefineConstants);NET461;NET461_OR_GREATER</DefineConstants>
<DefineConstants Condition="$([System.Version]::Parse('$(TargetFrameworkVersion.Substring(1))').CompareTo($([System.Version]::Parse('4.6')))) &gt;= 0">$(DefineConstants);NET46;NET46_OR_GREATER</DefineConstants>
<DefineConstants Condition="$([System.Version]::Parse('$(TargetFrameworkVersion.Substring(1))').CompareTo($([System.Version]::Parse('4.5.2')))) &gt;= 0">$(DefineConstants);NET452;NET452_OR_GREATER</DefineConstants>
<DefineConstants Condition="$([System.Version]::Parse('$(TargetFrameworkVersion.Substring(1))').CompareTo($([System.Version]::Parse('4.5.1')))) &gt;= 0">$(DefineConstants);NET451;NET451_OR_GREATER</DefineConstants>
<DefineConstants Condition="$([System.Version]::Parse('$(TargetFrameworkVersion.Substring(1))').CompareTo($([System.Version]::Parse('4.5')))) &gt;= 0">$(DefineConstants);NET45;NET45_OR_GREATER</DefineConstants>
<DefineConstants Condition="$([System.Version]::Parse('$(TargetFrameworkVersion.Substring(1))').CompareTo($([System.Version]::Parse('4.0')))) &gt;= 0">$(DefineConstants);NET40;NET40_OR_GREATER</DefineConstants>
<DefineConstants Condition="$([System.Version]::Parse('$(TargetFrameworkVersion.Substring(1))').CompareTo($([System.Version]::Parse('3.5')))) &gt;= 0">$(DefineConstants);NET35;NET35_OR_GREATER</DefineConstants>
<DefineConstants Condition="$([System.Version]::Parse('$(TargetFrameworkVersion.Substring(1))').CompareTo($([System.Version]::Parse('3.0')))) &gt;= 0">$(DefineConstants);NET30;NET30_OR_GREATER</DefineConstants>
<DefineConstants Condition="$([System.Version]::Parse('$(TargetFrameworkVersion.Substring(1))').CompareTo($([System.Version]::Parse('2.0')))) &gt;= 0">$(DefineConstants);NET20;NET20_OR_GREATER</DefineConstants>
</PropertyGroup>
</Project>

在工程文件中导入

1
2
3
4
<Project>
...
<Import Project="FrameworkSymbols.Common.prop" />
</Project>

使用

1
2
3
4
5
6
7
#if NET20
Console.WriteLine("NET20");
#endif
...
#if NET35_OR_GREATER
Console.WriteLine("NET35_OR_GREATER");
#endif

参考

Detect target framework version at compile time

C#预处理器指令