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

6

46

So I have a C# class library project that I only intend to use on Windows. It contains some classes that use the System.Drawing.Image class which is only available on Windows. After upgrading to Visual Studio 2022 and setting the target framework to .NET 6.0 I'm seeing a bunch of warnings that say:

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

See screenshot below for some examples:

"Error list" pane in Visual Studio 2022 showing several CA1416 "This call site is reachable on all platforms. '.' is only supported on: 'windows'." errors

In some sense, it's cool that VS2022 has scanned the library and found all the platform specific code that I'm using in the library. But I'd like to tell VS that I only plan to use the library on windows and it can mute all those warnings.

First I checked the Target framework option in the properties of the project but didn't seen any windows specific targets.

"Target framework" drop-down box on the Application → General page of a project's properties expanded to show available versions of .NET, .NET Core, and .NET Framework

Then I decided to edit the project's .csproj directly and changed the Target framework from

<TargetFramework>net6.0</TargetFramework>

to

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

But, sadly, even after a recompile, that didn't make the warnings go away either. So then I did some reading on the CA1416 warnings and sure enough it says in the Microsoft Docs that the target framework moniker is ignored for assessing this warning, however, VS does add an attribute to the project based on the TFM that influences this warning, but it only does so if the project is configured to generate the AssemblyInfo.cs file on the fly. But, alas, my project's AssemblyInfo.cs is maintained as a actual file rather then having it auto generated at build time.

So at this point, I'm ready to punt the ball and just disable CA1416 warnings for my project. So in the project's .proj file I added CA1416 for both the release and debug builds like so:

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

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

One would think that would be the end of those pesky warnings. (sigh) As it turns out, after rebuilding the project the warnings still show up. Got any suggestions? I'm all ears.

Sepoy answered 11/11, 2021 at 23:14 Comment(2)
I thought the lightbulb menu offered a few suppression options(line, file, project); do any of them work?Cq
@CaiusJard - You are correct. Not sure how I missed that and one of the options is to suppress via .editorconfig which is how I did it before seeing the suggestion drop down. Thanks for reminding me that this doesn't have to be hard. :-)Sepoy
K
16

Update:

Targeting Windows worked fine until one of our developers tried to start the solution on his Apple computer using Visual Studio 2022 for Mac Preview 1.

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

Reading .NET 6 Breaking changes Microsoft has a section about System.Drawing.Common.

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

Their recommendations are the following:

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.

Even though Microsoft.Maui.Graphics is in preview and is considered an experimental library I tried to use it given that Microsoft has the library as a recommended action library.

It seemed really promising at first but then I encountered a bug in their IImage Downsize method.

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

Until that is fixed my temporary solution is using Target framework .NET 6, Target OS (none) and then use Exclude specific warnings as errors given that we have enabled Treat warnings as errors.

enter image description here

I have also created a runtimeconfig.template.json in our web project root with the following values:

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

Original:

You can suppress the warning with dotnet_diagnostic.CA1416.severity = none but imao if you only intend to use it on Windows you should set Target OS to Windows for the project which will fix the warning.

enter image description here

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

Source:

https://mcmap.net/q/373451/-nuget-system-drawing-common-net-6-ca1416-this-call-site-is-reachable-on-all-platforms-39-image-fromstream-stream-39-is-only-supported-on-39-windows-39

Kareenkarel answered 8/12, 2021 at 9:23 Comment(6)
Not sure how I missed this setting. I switched the accepted answer to this one because I think this is the most obvious solution if one is only intending to run on Windows.Sepoy
This does not seem to work as of VS2022 V17.0.5 in Jan 2022. having TargetOS set to Windows, I still see CA1416 being reported. [SupportedOsPlatform("windows")] seems to be the better solution now.Sofer
mine does not seem to adhere to targetos either . Do you really need an assemblyinfo.cs to fix this?Kingkingbird
@Sofer Is every assembly where you get the warning really set to Target OS Windows? Sounds like a bug in that case to be honest. If it is related to System.Drawing.Common you have an alternative solution here: https://mcmap.net/q/373451/-nuget-system-drawing-common-net-6-ca1416-this-call-site-is-reachable-on-all-platforms-39-image-fromstream-stream-39-is-only-supported-on-39-windows-39Kareenkarel
If you vote down please say why. Very hard to improve answers otherwise.Kareenkarel
@Kareenkarel - Yes, I've verified that every assembly is set to "targetOS" Windows. However, one odd thing is that the same library whose code throws up the error in one Solution is re-used in another (windows-only) Solution yet doesn't throw up the error there!Sofer
L
51

I had success removing the CA1416 warnings by adding the following decorator to the top of the containing class:

[System.Runtime.Versioning.SupportedOSPlatform("windows")]

I'm only on VS2019 and using .net 5, but it may work for you. I tried this with VS2019 .net5 console project (top of class Program) and a .net5 class library (top of the class). I added the System.Common.Drawing nuget package. My code included:

string inputPath = @"C:\mypath\mypng.png";
Image i = Image.FromFile(inputPath);
Lawful answered 17/11, 2021 at 20:12 Comment(4)
I upvoted because this does work if the library is meant to be used from multiple platforms and you just want to call out that some of the classes is platform specific. But in my case I only intend to use my dlls on windows so it's easier to turn off CA1416 in one place then to put a SupportedOSPlatform attribute on a huge number of classes.Sepoy
I ran into this issue in a project where I had a "AssemblyInfo.cs" file instead of using the project properties: <GenerateAssemblyInfo>false</GenerateAssemblyInfo>. Here, I could declare the attribute in AssemblyInfo.cs: [assembly: System.Runtime.Versioning.SupportedOSPlatform("windows")]Inheritance
this is also described at microsoft, but i am not using c#.Hemimorphite
Works great for me. This was dealing with some security features that are Active Directory based. Current only supported on Windows.Newport
K
16

Update:

Targeting Windows worked fine until one of our developers tried to start the solution on his Apple computer using Visual Studio 2022 for Mac Preview 1.

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

Reading .NET 6 Breaking changes Microsoft has a section about System.Drawing.Common.

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

Their recommendations are the following:

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.

Even though Microsoft.Maui.Graphics is in preview and is considered an experimental library I tried to use it given that Microsoft has the library as a recommended action library.

It seemed really promising at first but then I encountered a bug in their IImage Downsize method.

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

Until that is fixed my temporary solution is using Target framework .NET 6, Target OS (none) and then use Exclude specific warnings as errors given that we have enabled Treat warnings as errors.

enter image description here

I have also created a runtimeconfig.template.json in our web project root with the following values:

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

Original:

You can suppress the warning with dotnet_diagnostic.CA1416.severity = none but imao if you only intend to use it on Windows you should set Target OS to Windows for the project which will fix the warning.

enter image description here

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

Source:

https://mcmap.net/q/373451/-nuget-system-drawing-common-net-6-ca1416-this-call-site-is-reachable-on-all-platforms-39-image-fromstream-stream-39-is-only-supported-on-39-windows-39

Kareenkarel answered 8/12, 2021 at 9:23 Comment(6)
Not sure how I missed this setting. I switched the accepted answer to this one because I think this is the most obvious solution if one is only intending to run on Windows.Sepoy
This does not seem to work as of VS2022 V17.0.5 in Jan 2022. having TargetOS set to Windows, I still see CA1416 being reported. [SupportedOsPlatform("windows")] seems to be the better solution now.Sofer
mine does not seem to adhere to targetos either . Do you really need an assemblyinfo.cs to fix this?Kingkingbird
@Sofer Is every assembly where you get the warning really set to Target OS Windows? Sounds like a bug in that case to be honest. If it is related to System.Drawing.Common you have an alternative solution here: https://mcmap.net/q/373451/-nuget-system-drawing-common-net-6-ca1416-this-call-site-is-reachable-on-all-platforms-39-image-fromstream-stream-39-is-only-supported-on-39-windows-39Kareenkarel
If you vote down please say why. Very hard to improve answers otherwise.Kareenkarel
@Kareenkarel - Yes, I've verified that every assembly is set to "targetOS" Windows. However, one odd thing is that the same library whose code throws up the error in one Solution is re-used in another (windows-only) Solution yet doesn't throw up the error there!Sofer
S
12

One way to solve this issue is to create an .editorconfig for the solution and then add the following line to that .editorconfig file:

dotnet_diagnostic.CA1416.severity = none

This will make all "Validate platform compatibility" warnings go away.

Sepoy answered 12/11, 2021 at 13:58 Comment(2)
Hi Ronc, glad to know you've found the solution to resolve this issue! Please consider accepting it as answer to change its status to Answered. Just a reminder :)Finnic
The simplest solution!Induction
H
2

After upgrading from Visual Studio 2017 with Dot Net 4.84 to Visual Studio 2022 with Dot NeT 7.0, i got for every occurrence of an external library one of this warnings, after contacting Microsoft and the GitHub Repo, was the solutiojn simple

enter image description here

As you see in the picture The upgrade process set the dot net Framework to 7.0 but the Version stayed on 7.0, but for Windows 7 there is no Dot Net 7.0 available.

Changing the version to Windows 10 and any sub number will get rid of all these warnings.

And if someone followed the Microsoft Webpage, which couldn't help

for vb net you need to write

<Assembly: System.Runtime.Versioning.SupportedOSPlatform("windows")>

but i didn't test it-

Hemimorphite answered 5/4, 2023 at 19:35 Comment(0)
P
0

Similar to what @RonC did, I was able to solve the problem by adding a Rule to my .ruleset file:

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

Just keep in mind that this will apply to the whole project for which the ruleset file is used.

Phallus answered 21/12, 2021 at 13:59 Comment(0)
C
-1

This now works for .net 8 and vs 2022. Change

<TargetFramework>net8.0</TargetFramework>

to

<TargetFramework>net8.0-windows</TargetFramework>
Caprine answered 24/11, 2023 at 21:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.