在编译时检查操作系统

本文关键字:操作系统 检查 编译 | 更新日期: 2023-09-27 18:10:03

我在我的开发机上运行Windows 7 64位操作系统,使用。net 4.5和MS Visual Studio 2012。我有几个c#项目使用System.Threading.Task命名空间。我希望能够在我们所有开发人员都可以访问的服务器上构建这些项目。问题是该服务器运行的是Windows server 2003,它不支持。net 4.5,而且System.Threading.Task命名空间在。net 4.5之前的版本中不存在。

我可以用一个编译时常数设置新的构建配置,我可以检查以确定要包含哪个命名空间,但在我这样做之前,我想知道是否已经有一个预定义的常数我可以使用。我对此表示怀疑,因为据我所知,编译时常量只能在c#中定义或不定义,而在c++中,它们可以有特定的值。

在编译时检查操作系统

首先,任务名称空间(或者更确切地说,任务名称空间)在。net 4.0中确实存在,尽管它的功能要有限得多(即:糖方法略少),而且没有async/await关键字。虽然有更多的限制,但这可能有助于打开简单地将程序的平台设置为。net 4.0的可能性,因为这解决了许多问题。

虽然你不能使用编译时间常量(即由const关键字标记的项)来排除/包含代码,但你可以使用符号定义通过#if指令来做到这一点。只要你正确地安排你的符号,这也可以是一种有效的方法来分离编译后的代码,因为&, |和嵌套的#if都是允许的,并按预期工作。

不管包含了什么命名空间,一个基于。net 4.5构建的程序仍然要运行4.5,并且不能在不支持4.5的机器上运行,即使你使用的所有特性都在4.0中可用。此外,您不能在每次构建配置时更改. net平台,但是您可以创建一个调用相同文件和文件夹的镜像项目,而不是针对4.0进行构建。总而言之,我建议使用4.0阅读以下更新并使用Mono。

更新:另一个选择可能是考虑Mono,根据他们的下载页面,最新的Mono保持与Windows XP和Server 2003的兼容性。我建议也使用Xamarin,这样你就可以在Mono平台上测试运行代码,但请注意,Mono读取与。net相同的IL, Xamarin被设计为读取/写入与vs相同的项目和解决方案格式。

在c#中,你需要自己定义os的常量。

在.csproj文件中执行以下操作

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
    <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="'$(IsLinux)'=='true'">
    <DefineConstants>_LINUX</DefineConstants>
  </PropertyGroup>
</Project>
之后在你的。cs文件中,你可以使用像 这样的常量
        #if _LINUX
           Console.WriteLine("This is Linux");
        #elif _WINDOWS
           Console.WriteLine("This is Windows");
        #else
            Console.WriteLine("Unknown os!");
        #endif

您也可以类似地检查OSX