确定.NET核心中的操作系统

本文关键字:操作系统 核心 NET 确定 | 更新日期: 2023-09-27 18:01:04

如何确定.NET Core应用程序运行在哪个操作系统上?在过去,我可以使用Environment.OSVersion

目前确定我的应用程序是在Mac还是Windows上运行的方法是什么?

确定.NET核心中的操作系统

方法

System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform()

可能的自变量

OSPlatform.Windows
OSPlatform.OSX
OSPlatform.Linux

示例

bool isWindows = System.Runtime.InteropServices.RuntimeInformation
                                               .IsOSPlatform(OSPlatform.Windows);

更新

感谢Oleksi-Vynnychenko 的评论

您可以使用以字符串形式获取操作系统名称和版本

var osNameAndVersion = System.Runtime.InteropServices.RuntimeInformation.OSDescription;

例如,osNameAndVersion将是Microsoft Windows 10.0.10586

System.Environment.OSVersion.Platform可以在完整的.NET Framework和Mono中使用,但是:

  • Mac OS X检测在Mono下几乎从未对我起过作用
  • 它没有在.NET Core中实现

System.Runtime.InteropServices.RuntimeInformation可以在.NET Core中使用,但是:

  • 它没有在完整的.NET Framework和Mono中实现
  • 它在运行时不执行平台检测,但使用硬编码信息
    (更多详细信息,请参阅corefx第3032期(

您可以pinvoke特定于平台的非托管函数,如uname(),但是:

  • 它可能会在未知平台上导致分段故障
  • 在某些项目中不允许

所以我建议的解决方案(见下面的代码(一开始可能看起来很傻,但:

  • 它使用100%托管代码
  • 它适用于.NET、Mono和.NET Core
  • 到目前为止,它在Pkcs11Interop图书馆的工作效果很好
string windir = Environment.GetEnvironmentVariable("windir");
if (!string.IsNullOrEmpty(windir) && windir.Contains(@"'") && Directory.Exists(windir))
{
    _isWindows = true;
}
else if (File.Exists(@"/proc/sys/kernel/ostype"))
{
    string osType = File.ReadAllText(@"/proc/sys/kernel/ostype");
    if (osType.StartsWith("Linux", StringComparison.OrdinalIgnoreCase))
    {
        // Note: Android gets here too
        _isLinux = true;
    }
    else
    {
        throw new UnsupportedPlatformException(osType);
    }
}
else if (File.Exists(@"/System/Library/CoreServices/SystemVersion.plist"))
{
    // Note: iOS gets here too
    _isMacOsX = true;
}
else
{
    throw new UnsupportedPlatformException();
}

检查System.OperatingSystem类,它为每个操作系统都有静态方法,即IsMacOS()IsWindows()IsIOS()等。这些方法从.NET 5开始就可用。

这使它成为一个很好的选择,因为这些方法的实现在编译OperatingSystem类的每个目标操作系统时使用预处理器指令将返回值固定为常量true/false。没有运行时探测或调用。

以下是OperatingSystem:中一个这样的方法的摘录

        /// <summary>
        /// Indicates whether the current application is running on Linux.
        /// </summary>
        [NonVersionable]
        public static bool IsLinux() =>
#if TARGET_LINUX && !TARGET_ANDROID
            true;
#else
            false;
#endif