Here is my C# code snippet:
if (Environment.IsWindows) {
_sessionAddress = GetSessionBusAddressFromSharedMemory();
}
...
[System.Runtime.Versioning.SupportedOSPlatform("windows")]
private static string GetSessionBusAddressFromSharedMemory() {
...
}
When I run the build, I get an error:
error CA1416: 'GetSessionBusAddressFromSharedMemory()' is supported on 'windows'
My logic is to invoke the method only when I am on Windows. How do I turn this warning off when building on Ubuntu? Regards.
Starting in .NET 5, the .NET SDK includes .NET source code analyzers. Several of these rules are enabled, by default, including CA1416. If your project contains code that violates this rule and is configured to treat warnings as errors, this change could break your build.
.NET code analyzer rule CA1416 is enabled, by default, starting in .NET 5. It produces a build warning for calls to platform-specific APIs from call sites that don't verify the operating system. Starting in .NET 5, the .NET SDK includes .NET source code analyzers.
In the future, we may introduce an analyzer that produces a warning in case of inconsistency. If you access an API annotated with these attributes from the context of a different platform, you can see CA1416 violations.
Some annotations on the API are ignored. In the future, we may introduce an analyzer that produces a warning in case of inconsistency. If you access an API annotated with these attributes from the context of a different platform, you can see CA1416 violations.
You can use a preprocessor directive to make sure that the method gets seen at compile time only in Windows:
#if Windows
private static string GetSessionBusAddressFromSharedMemory()
{
...
}
#endif
To define the directives you need to update your csproj as follows:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
</PropertyGroup>
<PropertyGroup Condition="'$(IsWindows)'=='true'">
<DefineConstants>Windows</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(IsOSX)'=='true'">
<DefineConstants>OSX</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(IsLinux)'=='true'">
<DefineConstants>Linux</DefineConstants>
</PropertyGroup>
</Project>
If you have control over the Environment.IsWindows
property you can apply [SupportedOSPlatformGuard("windows")]
attribute to that property:
public class Environment
{
[SupportedOSPlatformGuard("windows")]
public bool IsWindows => OperatingSystem.IsWindows;
}
Then the CA1416 analyzer would recognize the guard and would not warn within the conditional:
if (Environment.IsWindows) {
_sessionAddress = GetSessionBusAddressFromSharedMemory(); // no warning
}
For more info
You can switch to RuntimeInformation.IsOSPlatform
check. Next will give warning only for last clause:
public void M()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Console.WriteLine(GetSessionBusAddressFromSharedMemory());
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
Console.WriteLine(GetSessionBusAddressFromSharedMemoryUnix());
}
else
{
Console.WriteLine(GetSessionBusAddressFromSharedMemoryUnix()); // warning
}
}
[SupportedOSPlatform("windows")]
private static string GetSessionBusAddressFromSharedMemory()
{
return "win";
}
[SupportedOSPlatform("linux")]
private static string GetSessionBusAddressFromSharedMemoryUnix()
{
return "lin";
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With