确定.NET核心中的操作系统
本文关键字:操作系统 核心 NET 确定 | 更新日期: 2023-09-27 18:01:04
如何确定.NET Core应用程序运行在哪个操作系统上?在过去,我可以使用Environment.OSVersion
。
目前确定我的应用程序是在Mac还是Windows上运行的方法是什么?
方法
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