我们可以像这样为Platform Conditional Compilation in .NET Core添加自定义预处理器指令
<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>
我已经测试过,它工作正常。
现在,我要检测我是否在64位操作系统上。这是我的.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>
但是,当我运行此代码时,我的第一个if...else
可以正常工作,但是我的Is64BitOperatingSystem
预处理程序指令却没有运行
if (System.Environment.Is64BitOperatingSystem)
Console.WriteLine(64);
else
Console.WriteLine(32);
#if Is64BitOperatingSystem
Console.WriteLine(64);
#else
Console.WriteLine(32);
#endif
我在做什么错?我无法发现代码中的错误在哪里。
谢谢
要添加有关此内容的更多详细信息,我将此代码包含在.NET Core项目调用的.NET Standard库中。
我希望我的库检测它正在运行的当前体系结构(或已编译为,所以我可以做这样的事情
#if Is64BitOperatingSystem
[DllImport(@"Resources/HIDAPI/x64/hidapi")]
#else
[DllImport(@"Resources/HIDAPI/x32/hidapi")]
#endif
在调试之前,Visual Studio显然会编译我的应用程序,因此在此阶段使用System.Environment.Is64BitOperatingSystem
或预处理程序指令检查体系结构应得出相同的结果,但事实并非如此。我在64位计算机上,我的预处理程序指令告诉我我在32位体系结构上,即使我在Visual Studio Configuration Manager中将AnyCPU
更改为x64
请注意,this answer是Windows特定的,that one也是特定于Windows的,因为解决方案是从SetDllDirectory
调用kernel32.dll
函数
但是我希望我的代码能够在Linux上运行。
为了在此处共享最少的示例,我实际上删除了代码的错误部分。
看起来像这样可以得到预期的结果:
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Is64BitOperatingSystem Condition="'$([System.Environment]::Is64BitOperatingSystem)' == 'true'">true</Is64BitOperatingSystem>
</PropertyGroup>
<PropertyGroup Condition="'$(Is64BitOperatingSystem)'=='true'">
<DefineConstants>Is64BitOperatingSystem</DefineConstants>
</PropertyGroup>
但是这会产生错误的行为:
<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>
[有人可以向我解释吗?我不明白为什么添加IsWindows
条件会导致Is64BitOperatingSystem
预处理程序指令上的行为不同
之所以在上次编辑中不起作用的原因是DefineConstants
中的条件编译器常量不能单独定义,此属性的值是用分号分隔的值列表,应按以下方式定义
<PropertyGroup Condition="'$(IsWindows)'=='true'">
<DefineConstants>Windows</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Is64BitOperatingSystem)'=='true' And '$(IsWindows)'=='true'">
<DefineConstants>Windows;Is64BitOperatingSystem</DefineConstants>
</PropertyGroup>
并且以下代码将按预期工作
#if Windows
Console.WriteLine("built in Windows!");
#endif
#if Is64BitOperatingSystem
Console.WriteLine("built on x64");
#else
Console.WriteLine("built on x86");
#endif
Console.WriteLine(Environment.Is64BitOperatingSystem ? "running on x64" : "running on x86");
它将显示:
Windows内置!
基于x64构建
在x64上运行
但是它也会覆盖默认的DEBUG
和TRACE
常量,您也需要手动管理它们(如果需要)。 [Linux
常数
我希望我的库检测它正在运行(或已编译)的当前体系结构,因此我可以执行类似的操作
如果这是您的要求,那么我认为您在做错事。您尝试使用的方法将使库依赖于体系结构构建它的位置,而没有其他依赖。
编译指令,顾名思义,在编译时生效。它们在runtime无效。如果要为不同的体系结构使用不同的[DllImport]
,则将需要不同的版本。通常,解决方法是使用不同的构建配置。
在Configuration Manager中,创建两个单独的解决方案平台,以及相应的项目平台:
在“项目属性”->“构建”选项卡中,为两个条件之一指定条件编译指令:
在您的代码中,使用编译符号:
#if Is64Bit
[DllImport(@"Resources/HIDAPI/x64/hidapi")]
#else
[DllImport(@"Resources/HIDAPI/x32/hidapi")]
#endif