I have a .NET Core Console application. My goal here is to be able to conditionally DLLImport
a function and call it, but only on Windows runtimes.
I thought maybe if I could access the runtime identifier in the csproj
file, I could conditionally define a constant for that runtime, then in my c# I could surround the DLLImport and calls in #if
/#endif
blocks.
Is it possible to set compilation constants within a csproj
based on the runtime the project is being built for? This is specifically for an SDK-style Project format (that starts with <Project Sdk="Microsoft.NET.Sdk">
) that is targeting .NET Core.
Note: this question gets close, but is for project.json
style projects.
Alternately, is there a better approach to accomplish my goal?
If you are building and publishing for different runtimes by passing different --runtime
options (MSBuild property RuntimeIdentifier
), you can condition on that property in the csproj file (allowing you to use #if BUILT_FOR_WINDOWS
in your C# code):
<PropertyGroup>
<DefineConstants Condition="'$(RuntimeIdentifier)' == 'win-x64'">$(DefineConstants);BUILT_FOR_WINDOWS</DefineConstants>
</PropertyGroup>
However you can also test the current OS at run time using:
using System.Runtime.InteropServices;
…
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
// call windows function here
}
else
{
// do something else here
}
As long as a function marked with [DllImport(…)]
is not called on an OS where the library / method cannot be found, there shouldn't be any problems. Do note that DllImport()
can also probe for different libraries depending on the os - so DllImport("foo")
would check for foo.dll
, foo.dylib
, libfoo.so
etc.
Adding to a Martin Ullrich's answer: if you want to define constants based on RuntimeIdentifier
in a referenced library project as opposed to a project with application entry point make sure that you include the list of identifiers which you use in a RuntimeIdentifiers
property in the project's .csproj file, for example:
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RuntimeIdentifiers>linux-x64;linux-arm</RuntimeIdentifiers>
</PropertyGroup>
If you don't do it then the constants will not be defined as RuntimeIdentifier
property will not be passed to the csproj, as was in my case.
Source: https://github.com/dotnet/core/issues/2678#issuecomment-498967871
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