Определить операционную систему в .NET Core

118

Как я могу определить, в какой операционной системе работает мое приложение .NET Core? Раньше я мог использовать Environment.OSVersion.

Как в настоящее время определить, работает ли мое приложение на Mac или Windows?

dknaack
источник
stackoverflow.com/a/28664021/1009099 см. это
Ковпаев Алексей 05
Не совсем тот ответ, который я искал, но нашел его сам.
dknaack 05
См. Эту статью codepedia.info/…
Сатиндер Сингх

Ответы:

184

метод

System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform()

Возможный аргумент

OSPlatform.Windows
OSPlatform.OSX
OSPlatform.Linux

пример

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

Обновить

Спасибо за комментарий Алексея Винниченко

Вы можете получить название и версию операционной системы в виде строки, используя

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

Например, osNameAndVersionбыло быMicrosoft Windows 10.0.10586

dknaack
источник
4
Вы можете добавить, что для получения дополнительной информации об ОС в этом пакете есть еще одно свойство: System.Runtime.InteropServices.RuntimeInformation.OSDescription- возвращает описание ОС с версией и т. Д.
Алексей Винниченко
15
+1 хотя мне этот ответ не нравится. Почему они не могут просто реализовать System.Environment.OSVersion.Platformединообразие?
leppie 05
2
Обратите внимание, что константы не представляют все поддерживаемые ОС. Можно IsOSPlatform(OSPlatform.Create("FreeBSD"))проверить наличие других ОС, выяснив, поддерживаются ли они сейчас или могут быть добавлены в будущем. Однако не очень ясно, какой будет безопасный подход к тому, какие строки передать (например, имеет ли значение регистр или "bsd"соответствует обоим "FreeBSD"и "NetBSD"?). См. Обсуждение этой функции здесь .
NightOwl888,
37

System.Environment.OSVersion.Platform может использоваться в полной версии .NET Framework и Mono, но:

  • Обнаружение Mac OS X почти никогда не работало у меня в Mono
  • не реализовано в .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();
}
jariq
источник
1
Цените ваши усилия. Желаю, чтобы в будущем была некоторая последовательность.
leppie 05
6
System.Runtime.InteropServices.RuntimeInformation должен корректно работать в полной сети .net сейчас (с ноября), так что сейчас это кажется принятым "правильным" путем. Не уверен насчет моно, но поскольку они берут код прямо из .net теперь, когда он имеет открытый исходный код, это только вопрос времени, когда он там заработает, если еще не.
GrandOpener
1
Path.DirectorySeparatorChar Может использоваться, чтобы определить, является ли это машиной Windows или * nix.
kiran
InteropServices очень странные. В VStudio и Rider я иногда получаю сообщение «Неизвестно в этом контексте» или он компилируется.
Понятия