Określ system operacyjny w .NET Core

118

Jak mogę określić, w którym systemie operacyjnym działa moja aplikacja .NET Core? W przeszłości mogłem użyć Environment.OSVersion.

Jaki jest obecny sposób określenia, czy moja aplikacja działa na komputerze Mac czy Windows?

dknaack
źródło
stackoverflow.com/a/28664021/1009099 zobacz to
Kovpaev Alexey
Nie do końca to odpowiedź, której szukałem, ale znalazłem ją sam.
dknaack
Zapoznaj się z tym artykułem codepedia.info/…
Satinder singh

Odpowiedzi:

184

metoda

System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform()

Możliwy argument

OSPlatform.Windows
OSPlatform.OSX
OSPlatform.Linux

Przykład

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

Aktualizacja

Dzięki komentarzowi Oleksii Vynnychenko

Nazwę i wersję systemu operacyjnego można uzyskać jako ciąg znaków za pomocą

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

Np. osNameAndVersionByłobyMicrosoft Windows 10.0.10586

dknaack
źródło
4
Możesz dodać, że aby uzyskać więcej informacji na temat systemu operacyjnego, w tym pakiecie jest jeszcze jedna właściwość: System.Runtime.InteropServices.RuntimeInformation.OSDescription- zwraca opis systemu operacyjnego z wersją itp.
Oleksii Vynnychenko
15
+1, chociaż nie podoba mi się ta odpowiedź. Dlaczego nie mogą po prostu wdrożyć System.Environment.OSVersion.Platformdla spójności?
leppie
2
Zauważ, że stałe nie reprezentują wszystkich obsługiwanych systemów operacyjnych. Możliwe jest badanie innych systemów operacyjnych, sprawdzając, IsOSPlatform(OSPlatform.Create("FreeBSD"))czy są one obsługiwane teraz, czy mogą zostać dodane w przyszłości. Jednak nie jest bardzo jasne, jakie byłoby bezpieczne podejście do przekazywania ciągów (na przykład czy wielkość liter ma znaczenie, czy "bsd"pasuje do obu "FreeBSD"i "NetBSD"?). Zobacz dyskusję na temat tej funkcji tutaj .
NightOwl888,
37

System.Environment.OSVersion.Platform może być używany w pełnej wersji .NET Framework i Mono, ale:

  • Wykrywanie Mac OS X prawie nigdy nie działało w Mono
  • nie jest zaimplementowany w .NET Core

System.Runtime.InteropServices.RuntimeInformation może być używany w .NET Core, ale:

  • nie jest zaimplementowany w pełnej wersji .NET Framework i Mono
  • nie wykrywa platformy w czasie wykonywania, ale zamiast tego używa zakodowanych na stałe informacji
    ( więcej szczegółów w numerze 3032 corefx )

Możesz pinvoke niezarządzane funkcje specyficzne dla platformy, takie jak uname()ale:

  • może to spowodować błąd segmentacji na nieznanych platformach
  • nie jest dozwolone w niektórych projektach

Tak więc moje sugerowane rozwiązanie (patrz kod poniżej) może na początku wyglądać ostro, ale:

  • używa w 100% zarządzanego kodu
  • działa w .NET, Mono i .NET Core
  • jak dotąd działa jak urok w bibliotece 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
źródło
1
Doceń swój wysiłek. Chciałbym, żeby w przyszłości była jakaś konsekwencja.
leppie
6
System.Runtime.InteropServices.RuntimeInformation powinien teraz działać poprawnie w pełnej wersji .net (od listopada), więc teraz wydaje się, że jest to akceptowany „właściwy” sposób. Nie jestem pewien co do mono, ale ponieważ pobierają kod bezpośrednio z .net teraz, gdy jest to open source, to tylko kwestia czasu, zanim będzie tam działać, jeśli nie już.
GrandOpener
1
Path.DirectorySeparatorChar Może służyć do określenia, czy jest to maszyna z systemem Windows, czy * nix.
kiran
Usługi InteropServices są bardzo dziwne. W VStudio i Rider czasami pojawia się komunikat „Nieznany w tym kontekście” lub kompiluje się. Nie mam pojęcia o przyczynie tego niepowodzenia ...
Ślesa