【发布时间】:2020-04-07 15:04:12
【问题描述】:
我们可以像这样为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 配置管理器中将 AnyCPU 更改为 x64
请注意,this answer 是特定于 Windows 的,that one 也是因为解决方案是从 kernel32.dll 调用 SetDllDirectory 函数
但我希望我的代码能够在 Linux 上运行。
编辑 2:
为了在这里分享一个最小的示例,我实际上删除了代码中的错误部分。
看起来这给出了预期的结果:
<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 预处理器指令上的不同行为
【问题讨论】:
-
当您说它不起作用时,请解释您的意思。你实际上在做什么来尝试这个?
if (System.Environment.Is64BitOperatingSystem)和#if Is64BitOperatingSystem在这里表示非常不同的东西。第一个取决于代码的运行位置。第二个取决于代码在哪里编译。 -
所以这实际上不是您的 .csproj 文件,您发布的内容已损坏。
-
@HansPassant 我发布的内容没有损坏,第一个代码块是我链接的博客文章的引用,因为这是 SO 的一个好习惯。我为第二个代码块写了
Here is my .csproj -
@JérômeMEVEL 您的
csproj文件中有多余的关闭</PropertyGroup>标记。我也无法重现您的问题,Is64BitOperatingSystem按预期工作 -
@PavelAnikhouski 哎呀,这只是一个复制粘贴问题。现在我的 .NET Standard 库和我的 .NET Core 项目都有
<Platforms>x64</Platforms>,我重新编译了我的代码,但我仍然遇到问题
标签: c# .net-core msbuild .net-standard preprocessor-directive