如何修复 Visual Studio 2022 警告 CA1416 "Call site reachable by all platforms" 但 "only supported on: 'windows'"?

How to fix Visual Studio 2022 Warning CA1416 "Call site reachable by all platforms" but "only supported on: 'windows'"?

所以我有一个 C# class 库项目,我只打算在 Windows 上使用。它包含一些使用 System.Drawing.Image class 的 classes,仅在 Windows 上可用。升级到 Visual Studio 2022 并将目标框架设置为 .NET 6.0 后,我看到了一堆警告:

CA1416 "This call site is reachable on all platforms. 'SomeClass.SomeMethod' is only supported on: 'windows'.

有关示例,请参见下面的屏幕截图:

从某种意义上说,VS2022 扫描了库并找到了我在库中使用的所有平台特定代码,这很酷。但我想告诉 VS,我只打算在 windows 上使用该库,它可以消除所有这些警告。

首先我检查了项目属性中的 Target framework 选项,但没有看到任何 windows 特定目标。

然后我决定直接编辑项目的 .csproj 并将 Target framework

<TargetFramework>net6.0</TargetFramework>

<TargetFramework>net6.0-windows</TargetFramework>

但是,遗憾的是,即使在重新编译之后,警告也没有消失。因此,我对 CA1416 警告进行了一些阅读,果然它在 Microsoft Docs 中说在评估此警告时忽略了目标框架名字对象,但是,VS 确实向项目添加了一个属性基于影响此警告的 TFM,但只有在项目配置为动态生成 AssemblyInfo.cs 文件时才会这样做。但是,唉,我的项目的 AssemblyInfo.cs 是作为实际文件维护的,而不是在构建时自动生成的。

所以在这一点上,我已准备好投入球并为我的项目禁用 CA1416 警告。因此,在项目的 .proj 文件中,我为发布和调试版本添加了 CA1416,如下所示:

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <NoWarn>1701;1702;CA1416;</NoWarn>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
    <NoWarn>1701;1702;CA1416;</NoWarn>
</PropertyGroup>

人们会认为那些讨厌的警告就此结束。 (叹) 事实证明,在重建项目后,警告 still 出现了。有什么建议吗?我洗耳恭听。

解决此问题的一种方法是为解决方案创建一个 .editorconfig,然后将以下行添加到该 .editorconfig 文件:

dotnet_diagnostic.CA1416.severity = none

这将使所有“验证平台兼容性”警告消失。

我通过将以下装饰器添加到包含 class:

的顶部,成功删除了 CA1416 警告
[System.Runtime.Versioning.SupportedOSPlatform("windows")]

我只在 VS2019 上使用 .net 5,但它可能适合你。我尝试使用 VS2019 .net5 控制台项目(class 程序的顶部)和 .net5 class 库(class 的顶部)。 我添加了 System.Common.Drawing nuget 包。 我的代码包括:

string inputPath = @"C:\mypath\mypng.png";
Image i = Image.FromFile(inputPath);

更新:

定位 Windows 工作正常,直到我们的一位开发人员尝试使用 Visual Studio 2022 for Mac Preview 1 在他的 Apple 计算机上启动解决方案。

https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1416

阅读 .NET 6 Breaking changes Microsoft 有一节关于 System.Drawing.Common

https://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/6.0/system-drawing-common-windows-only

他们的建议如下:

To use these APIs for cross-platform apps, migrate to one of the following libraries:

  • ImageSharp
  • [SkiaSharp][2]
  • [Microsoft.Maui.Graphics][3]

Alternatively, you can enable support for non-Windows platforms by setting the System.Drawing.EnableUnixSupport runtime configuration switch to true in the runtimeconfig.json file:

{
   "runtimeOptions": {
      "configProperties": {
         "System.Drawing.EnableUnixSupport": true
      }
   }
}

This configuration switch was added to give cross-platform apps that depend heavily on this package time to migrate to more modern libraries. However, non-Windows bugs will not be fixed. In addition, we may completely remove support for non-Windows platforms in a future release, even if you enable it using the runtime configuration switch.

Note

Despite the name of the runtime switch, System.Drawing.EnableUnixSupport, it applies to various non-Windows platforms, such as macOS and Android, which can generally be considered flavors of Unix.

尽管 Microsoft.Maui.Graphics 处于预览状态并且被认为是一个实验库,但我还是尝试使用它,因为 Microsoft 将该库作为推荐的操作库。

起初看起来很有希望,但后来我在他们的 IImage Downsize 方法中遇到了一个错误。

https://github.com/dotnet/Microsoft.Maui.Graphics/issues/247

在解决这个问题之前,我的临时解决方案是使用 Target framework .NET 6,Target OS (none),然后使用 Exclude specific warnings as errors,因为我们已经启用 Treat warnings as errors.

我还在我们的 Web 项目根目录中创建了一个具有以下值的 runtimeconfig.template.json

{
   "runtimeOptions": {
      "configProperties": {
         "System.Drawing.EnableUnixSupport": true
      }
   }
}

原文:

您可以使用 dotnet_diagnostic.CA1416.severity = none 抑制警告,但是如果您只打算在 Windows 上使用它,您应该将目标 OS 设置为 Windows将修复警告。

https://docs.microsoft.com/en-us/dotnet/core/compatibility/code-analysis/5.0/ca1416-platform-compatibility-analyzer

来源:

与@RonC 所做的类似,我能够通过向我的 .ruleset 文件添加规则来解决问题:

<Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis" RuleNamespace="Microsoft.Rules.Managed">  
  <Rule Id="CA1416" Action="None"/>
</Rules>  

请记住,这将应用于使用规则集文件的整个项目。