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?



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


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();
}

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.