确定.NET Core中的操作系统


Answers:


184

方法

System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform()

可能的论点

OSPlatform.Windows
OSPlatform.OSX
OSPlatform.Linux

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

更新资料

感谢Oleksii Vynnychenko的评论

您可以使用以下命令将操作系统名称和版本作为字符串获取

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

例如osNameAndVersionMicrosoft Windows 10.0.10586


4
您可以添加到获得操作系统的信息有在包装的另一个特性:System.Runtime.InteropServices.RuntimeInformation.OSDescription-与版本OS的收益说明等等
奥莱克西Vynnychenko

15
+1,尽管我不喜欢这个答案。他们为什么不能仅仅System.Environment.OSVersion.Platform为了一致性而实施?
勒皮

2
请注意,这些常数并不代表所有受支持的OS。可以通过使用IsOSPlatform(OSPlatform.Create("FreeBSD"))现在支持还是将来添加来探查其他OS 。但是,对于通过什么字符串(例如,大小写是否重要,或者是否与?"bsd"匹配),哪种方法是安全的方法还不是很清楚。在此处查看有关此功能的讨论。"FreeBSD""NetBSD"
NightOwl888

37

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

  • 在Mono下,Mac OS X检测几乎对我不起作用
  • .NET Core中未实现

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

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

您可以调用平台特定的非托管功能,例如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();
}

1
感谢您的努力。希望将来能保持一定的一致性。
leppie

6
System.Runtime.InteropServices.RuntimeInformation现在应该在完整的.net中正常运行(自11月以来),因此这似乎是目前公认的“正确”方法。不确定mono是什么,但是由于它们是开放源代码,因此他们现在已经从.net直接获取一些代码,因此即使不在那里工作也只是时间问题。
GrandOpener

1
Path.DirectorySeparatorChar可用于确定它是Windows还是* nix机器。
基兰

InteropServices非常奇怪。在VStudio和Rider中,有时会出现“在这种情况下未知”或被编译的情况。不知道这次失败的原因...
Slesa
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.