多目标框架(net472;net8.0-windows)编译时出现TargetPlatformAttribute及SupportedOSPlatformAttribute访问权限错误的解决方案咨询
最近我们团队正逐步把项目从.NET 4x迁移到.NET 8,不过遇到了个棘手的问题——有些依赖是Windows专属的,所以得用net8.0-windows作为目标框架,而不是net8.0或者netstandard2.0这类通用框架。
本来以为这事挺简单的,就在项目文件里配置了多目标框架:
<TargetFrameworks>net472;net8.0-windows</TargetFrameworks>
结果编译的时候直接炸了,弹出两个错误:
'TargetPlatformAttribute' is inaccessible due to its protection level
'SupportedOSPlatformAttribute' is inaccessible due to its protection level
查了一圈才搞明白,原来编译器会自动生成AssemblyInfo.cs文件,里面自动加了这两个属性来标记目标平台:
[assembly: System.Runtime.Versioning.TargetPlatformAttribute("Windows7.0")] [assembly: System.Runtime.Versioning.SupportedOSPlatformAttribute("Windows7.0")]
但问题出在,这两个属性是.NET Core/.NET 5+才引入的,.NET Framework 4.7.2里根本没有这玩意儿,所以多目标编译的时候,针对.NET 4.7.2的编译阶段就找不到这些属性,直接报访问权限错误了。
这里给几个亲测有效的解决办法:
方法一:禁用自动生成的平台相关属性
在项目文件里添加配置,告诉编译器不要自动生成这些平台属性,我们自己手动控制:
<PropertyGroup> <!-- 禁用自动生成的TargetPlatform和SupportedOSPlatform属性 --> <GenerateTargetPlatformAttribute>false</GenerateTargetPlatformAttribute> <GenerateSupportedOSPlatformAttribute>false</GenerateSupportedOSPlatformAttribute> </PropertyGroup>
之后可以手动在AssemblyInfo.cs里通过条件编译来添加这些属性,只在.NET 8及以上的目标里生效:
#if NET8_0_OR_GREATER [assembly: System.Runtime.Versioning.TargetPlatformAttribute("Windows7.0")] [assembly: System.Runtime.Versioning.SupportedOSPlatformAttribute("Windows7.0")] #endif
方法二:通过条件编译控制属性生成
如果不想完全禁用自动生成,也可以在项目文件里通过条件属性来控制,只针对.NET 8及以上的目标生成这些属性:
<PropertyGroup Condition="'$(TargetFramework)' == 'net8.0-windows'"> <GenerateTargetPlatformAttribute>true</GenerateTargetPlatformAttribute> <GenerateSupportedOSPlatformAttribute>true</GenerateSupportedOSPlatformAttribute> </PropertyGroup> <PropertyGroup Condition="'$(TargetFramework)' == 'net472'"> <GenerateTargetPlatformAttribute>false</GenerateTargetPlatformAttribute> <GenerateSupportedOSPlatformAttribute>false</GenerateSupportedOSPlatformAttribute> </PropertyGroup>
这样编译的时候,针对.NET 4.7.2就不会生成这些属性,自然也就不会报错了。亲测这两种方法都能解决问题,你可以根据自己项目的情况选一个合适的~
备注:内容来源于stack exchange,提问作者Spencer Farley

