我可以根据 .NET Core 中的运行时标识符定义常量吗?
Can I define constants based on the runtime identifier in .NET Core?
我有一个 .NET Core 控制台应用程序。我的目标是能够有条件地 DLLImport
一个函数并调用它,但仅限于 Windows 运行时。
我想也许如果我可以访问 csproj
文件中的运行时标识符,我可以有条件地为该运行时定义一个常量,然后在我的 c# 中我可以包围 DLLImport 并调用 #if
/#endif
块。
是否可以根据正在构建项目的运行时在 csproj
中设置编译常量?这是专门针对 .NET Core 的 SDK 样式项目格式(以 <Project Sdk="Microsoft.NET.Sdk">
开头)。
注意: 接近,但适用于 project.json
风格的项目。
或者,是否有更好的方法来实现我的目标?
如果您通过传递不同的 --runtime
选项 (MSBuild 属性 RuntimeIdentifier
) 构建和发布不同的 运行 次,您可以 属性 在 csproj 文件中(允许您在 C# 代码中使用 #if BUILT_FOR_WINDOWS
):
<PropertyGroup>
<DefineConstants Condition="'$(RuntimeIdentifier)' == 'win-x64'">$(DefineConstants);BUILT_FOR_WINDOWS</DefineConstants>
</PropertyGroup>
但是您也可以在 运行 时间使用以下方法测试当前 OS:
using System.Runtime.InteropServices;
…
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
// call windows function here
}
else
{
// do something else here
}
只要标有[DllImport(…)]
的函数不在找不到库/方法的OS上调用,就不会有任何问题。请注意 DllImport()
也可以根据 os 探测不同的库 - 所以 DllImport("foo")
会检查 foo.dll
、foo.dylib
、libfoo.so
等.
添加到 Martin Ullrich 的回答:如果您想在引用的库项目中基于 RuntimeIdentifier
定义常量,而不是在具有应用程序入口点的项目中,请确保包含您所使用的标识符列表在项目的 .csproj 文件中的 RuntimeIdentifiers
属性 中使用,例如:
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RuntimeIdentifiers>linux-x64;linux-arm</RuntimeIdentifiers>
</PropertyGroup>
如果您不这样做,那么常量将不会被定义为 RuntimeIdentifier
属性 将不会像我的情况一样传递给 csproj。
来源:https://github.com/dotnet/core/issues/2678#issuecomment-498967871
我有一个 .NET Core 控制台应用程序。我的目标是能够有条件地 DLLImport
一个函数并调用它,但仅限于 Windows 运行时。
我想也许如果我可以访问 csproj
文件中的运行时标识符,我可以有条件地为该运行时定义一个常量,然后在我的 c# 中我可以包围 DLLImport 并调用 #if
/#endif
块。
是否可以根据正在构建项目的运行时在 csproj
中设置编译常量?这是专门针对 .NET Core 的 SDK 样式项目格式(以 <Project Sdk="Microsoft.NET.Sdk">
开头)。
注意:project.json
风格的项目。
或者,是否有更好的方法来实现我的目标?
如果您通过传递不同的 --runtime
选项 (MSBuild 属性 RuntimeIdentifier
) 构建和发布不同的 运行 次,您可以 属性 在 csproj 文件中(允许您在 C# 代码中使用 #if BUILT_FOR_WINDOWS
):
<PropertyGroup>
<DefineConstants Condition="'$(RuntimeIdentifier)' == 'win-x64'">$(DefineConstants);BUILT_FOR_WINDOWS</DefineConstants>
</PropertyGroup>
但是您也可以在 运行 时间使用以下方法测试当前 OS:
using System.Runtime.InteropServices;
…
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
// call windows function here
}
else
{
// do something else here
}
只要标有[DllImport(…)]
的函数不在找不到库/方法的OS上调用,就不会有任何问题。请注意 DllImport()
也可以根据 os 探测不同的库 - 所以 DllImport("foo")
会检查 foo.dll
、foo.dylib
、libfoo.so
等.
添加到 Martin Ullrich 的回答:如果您想在引用的库项目中基于 RuntimeIdentifier
定义常量,而不是在具有应用程序入口点的项目中,请确保包含您所使用的标识符列表在项目的 .csproj 文件中的 RuntimeIdentifiers
属性 中使用,例如:
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RuntimeIdentifiers>linux-x64;linux-arm</RuntimeIdentifiers>
</PropertyGroup>
如果您不这样做,那么常量将不会被定义为 RuntimeIdentifier
属性 将不会像我的情况一样传递给 csproj。
来源:https://github.com/dotnet/core/issues/2678#issuecomment-498967871