We can add custom preprocessor directives for Platform Conditional Compilation in .NET Core like this
<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>
I've tested, it's working fine.
Now I want to detect whether or not I'm on a 64 bits operating system. Here is my .csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Is64BitOperatingSystem Condition="'$([System.Environment]::Is64BitOperatingSystem)' == 'true'">true</Is64BitOperatingSystem>
</PropertyGroup>
<PropertyGroup Condition="'$(Is64BitOperatingSystem)'=='true'">
<DefineConstants>Is64BitOperatingSystem</DefineConstants>
</PropertyGroup>
</Project>
However when I run this code, my first if...else
is working as expected but not my Is64BitOperatingSystem
preprocessor directive
if (System.Environment.Is64BitOperatingSystem)
Console.WriteLine(64);
else
Console.WriteLine(32);
#if Is64BitOperatingSystem
Console.WriteLine(64);
#else
Console.WriteLine(32);
#endif
What am I doing wrong? I can't spot where's the mistake in my code.
Thank you
EDIT
To add more details about this, I included this code in a .NET Standard library that is called by a .NET Core project.
I want my library to detect the current architecture it's running on (or has been compiled for) so I can do something like this
#if Is64BitOperatingSystem
[DllImport(@"Resources/HIDAPI/x64/hidapi")]
#else
[DllImport(@"Resources/HIDAPI/x32/hidapi")]
#endif
Before debugging, Visual Studio obviously compiles my application so at this stage checking the architecture using System.Environment.Is64BitOperatingSystem
or a preprocessor directive should give the same results but it's not. I'm on a 64 bits machine and my preprocessor directive tells me I'm on a 32 bits architecture even if I change AnyCPU
to x64
in Visual Studio Configuration Manager
Note that this answer is Windows specific and that one too because the solution is to call the SetDllDirectory
function from kernel32.dll
But I want my code to be able to run on Linux.
EDIT 2:
For the sake of sharing a minimal sample here I actually removed the faulty part of my code.
It looks like this gives the expected result:
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Is64BitOperatingSystem Condition="'$([System.Environment]::Is64BitOperatingSystem)' == 'true'">true</Is64BitOperatingSystem>
</PropertyGroup>
<PropertyGroup Condition="'$(Is64BitOperatingSystem)'=='true'">
<DefineConstants>Is64BitOperatingSystem</DefineConstants>
</PropertyGroup>
But this gives a faulty behavior:
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Is64BitOperatingSystem Condition="'$([System.Environment]::Is64BitOperatingSystem)' == 'true'">true</Is64BitOperatingSystem>
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
</PropertyGroup>
<PropertyGroup Condition="'$(Is64BitOperatingSystem)'=='true'">
<DefineConstants>Is64BitOperatingSystem</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(IsWindows)'=='true'">
<DefineConstants>Windows</DefineConstants>
</PropertyGroup>
If anybody could explain me that?
I don't understand why adding the IsWindows
condition is responsible for a different behavior on the Is64BitOperatingSystem
preprocessor directive