Determina il sistema operativo in .NET Core


118

Come posso determinare su quale sistema operativo è in esecuzione la mia app .NET Core? In passato potevo usare Environment.OSVersion.

Qual è il modo attuale per determinare se la mia app è in esecuzione su Mac o Windows?



Non proprio la risposta che stavo cercando, ma l'ho trovata da solo.
dknaack

Fare riferimento a questo articolo codepedia.info/…
Satinder singh

Risposte:


184

Metodo

System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform()

Possibile argomento

OSPlatform.Windows
OSPlatform.OSX
OSPlatform.Linux

Esempio

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

Aggiornare

Grazie al commento di Oleksii Vynnychenko

È possibile ottenere il nome e la versione del sistema operativo come stringa utilizzando

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

Ad esempio, osNameAndVersionsarebbeMicrosoft Windows 10.0.10586


4
Puoi aggiungerlo per ottenere maggiori informazioni sul sistema operativo, c'è un'altra proprietà in quel pacchetto: System.Runtime.InteropServices.RuntimeInformation.OSDescription- restituisce la descrizione del sistema operativo con la versione, ecc.
Oleksii Vynnychenko

15
+1 anche se non mi piace questa risposta. Perché non possono implementare solo System.Environment.OSVersion.Platformper coerenza?
leppie il

2
Notare che le costanti non rappresentano tutti i sistemi operativi supportati. È possibile cercare altri sistemi operativi utilizzando IsOSPlatform(OSPlatform.Create("FreeBSD"))se sono supportati ora o possono essere aggiunti in futuro. Tuttavia, non è molto chiaro quale sarebbe un approccio sicuro per quali stringhe passare (ad esempio, il caso è importante o "bsd"corrisponde a entrambi "FreeBSD"e "NetBSD"?). Vedi la discussione su questa funzione qui .
NightOwl888

37

System.Environment.OSVersion.Platform può essere utilizzato in .NET Framework completo e Mono ma:

  • Il rilevamento di Mac OS X non ha quasi mai funzionato per me in Mono
  • non è implementato in .NET Core

System.Runtime.InteropServices.RuntimeInformation può essere utilizzato in .NET Core ma:

  • non è implementato in .NET Framework completo e Mono
  • non esegue il rilevamento della piattaforma in runtime ma utilizza invece informazioni hardcoded
    (vedere corefx problema # 3032 per maggiori dettagli)

È possibile bloccare funzioni non gestite specifiche della piattaforma come uname()ma:

  • può causare errori di segmentazione su piattaforme sconosciute
  • non è consentito in alcuni progetti

Quindi la mia soluzione suggerita (vedi il codice qui sotto) potrebbe sembrare saggia all'inizio ma:

  • utilizza codice gestito al 100%
  • funziona in .NET, Mono e .NET Core
  • finora funziona come un incantesimo nella libreria 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
Apprezzo per il tuo impegno. Vorrei che ci fosse un po 'di coerenza in futuro.
leppie il

6
System.Runtime.InteropServices.RuntimeInformation dovrebbe funzionare correttamente in full .net ora (da novembre), quindi sembra essere il modo "giusto" accettato ora. Non sono sicuro del mono, ma poiché stanno prendendo del codice direttamente da .net ora che è open source, è solo questione di tempo prima che funzioni, se non già.
GrandOpener

1
Path.DirectorySeparatorChar Può essere utilizzato per determinare se è una macchina Windows o * nix.
kiran

InteropServices sono molto strani. All'interno di VStudio e Rider, a volte ottengo "Sconosciuto in questo contesto" o si compila. Non
ho
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.