【问题标题】:Check the operating system at compile time?在编译时检查操作系统?
【发布时间】:2014-08-14 00:12:44
【问题描述】:

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

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

【问题讨论】:

  • 为什么不使用Microsoft.Bcl nuget 包? nuget.org/packages/Microsoft.Bcl
  • 使用相同代码定位 2 个版本的框架有点痛苦 - 您是否考虑过仅定位 4.0(可能与作为期货或 CTP 发布的任务库的 4.5 之前版本)或升级服务器到2012 年?
  • 打算评论 Sav 的回答。这是一个运行时常量,但您可以使用 powershell/build 脚本来访问运行时常量,然后传递/定义编译标志/符号以传递给编译步骤。这样做可能比这样做更麻烦。
  • 考虑将标题更改为“如何在支持旧 .NET 的旧服务器操作系统上构建 .NET 4.5 应用程序?”
  • @AaronLS 同意,这看起来像 XY problem

标签: c# visual-studio-2012


【解决方案1】:

首先,.NET 4.0 中确实存在 Task 命名空间(或者更确切地说是 Tasks 命名空间),尽管它的功能更加有限(阅读:糖方法略少)并且没有 async/await 关键字。尽管受到更多限制,但这可能有助于将程序平台简单地设置为 .NET 4.0,因为这可以解决您的很多问题。

虽然您不能使用编译时常量(即由 const 关键字标记的项目)来排除/包含代码,但您可以通过#if directive 使用符号定义来执行此操作。只要您正确排列符号,这也可以成为分隔已编译代码的有效方法,因为 &、| 和嵌套的 #if 都允许并按预期工作。

但是,无论包含哪些命名空间,针对 .NET 4.5 构建的程序仍将运行 4.5,并且无法在不支持它的机器上运行,即使您使用的所有功能都在 4.0 中可用。此外,您无法更改每个构建配置的 .NET 平台,但您可能可以通过创建一个调用相同文件和文件夹的镜像项目而侥幸逃脱,而是针对 4.0 构建。总而言之,我建议 going 4.0 阅读以下更新并改用 Mono。

更新:另一种选择可能是考虑Mono,因为根据他们的Download Page,最新的 Mono 保持与 Windows XP 和 Server 2003 的兼容性。我建议您也购买 Xamarin,以便您可以针对Mono 平台,但请注意,Mono 读取的 IL 与 .NET 相同,而 Xamarin 旨在读取/写入与 VS 相同的项目和解决方案格式。

【讨论】:

    【解决方案2】:

    在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。

    【讨论】:

      猜你喜欢
      • 2010-09-18
      • 2023-03-18
      • 2012-04-24
      • 1970-01-01
      • 1970-01-01
      • 2013-02-11
      • 1970-01-01
      • 2018-09-10
      • 1970-01-01
      相关资源
      最近更新 更多