Déterminer le système d'exploitation dans .NET Core

118

Comment puis-je déterminer sur quel système d'exploitation mon application .NET Core s'exécute? Dans le passé, je pouvais utiliser Environment.OSVersion.

Quelle est la méthode actuelle pour déterminer si mon application s'exécute sur Mac ou Windows?

dknaack
la source
stackoverflow.com/a/28664021/1009099 voir ça
Kovpaev Alexey
Pas vraiment la réponse que je cherchais, mais je l'ai trouvée par moi-même.
dknaack
Reportez-vous à cet article codepedia.info
Satinder singh

Réponses:

184

Méthode

System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform()

Argument possible

OSPlatform.Windows
OSPlatform.OSX
OSPlatform.Linux

Exemple

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

Mettre à jour

Merci au commentaire d'Oleksii Vynnychenko

Vous pouvez obtenir le nom et la version du système d'exploitation sous forme de chaîne en utilisant

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

Par exemple osNameAndVersionseraitMicrosoft Windows 10.0.10586

dknaack
la source
4
Vous pouvez ajouter cela pour obtenir plus d'informations sur le système d'exploitation, il y a une autre propriété dans ce package: System.Runtime.InteropServices.RuntimeInformation.OSDescription- renvoie la description du système d'exploitation avec la version, etc.
Oleksii Vynnychenko
15
+1 bien que je n'aime pas cette réponse. Pourquoi ne peuvent-ils pas simplement mettre en œuvre System.Environment.OSVersion.Platformpour la cohérence?
leppie
2
Notez que les constantes ne représentent pas tous les systèmes d'exploitation pris en charge. Il est possible de rechercher d'autres systèmes d'exploitation en utilisant IsOSPlatform(OSPlatform.Create("FreeBSD"))s'ils sont pris en charge maintenant ou s'ils peuvent être ajoutés à l'avenir. Cependant, il n'est pas très clair quelle serait une approche sûre pour les chaînes à passer (par exemple, la casse est-elle importante ou "bsd"correspond-elle aux deux "FreeBSD"et "NetBSD"?). Voir la discussion sur cette fonctionnalité ici .
NightOwl888
37

System.Environment.OSVersion.Platform peut être utilisé dans le .NET Framework complet et Mono mais:

  • La détection de Mac OS X n'a ​​presque jamais fonctionné pour moi sous Mono
  • il n'est pas implémenté dans .NET Core

System.Runtime.InteropServices.RuntimeInformation peut être utilisé dans .NET Core mais:

  • il n'est pas implémenté dans le plein .NET Framework et Mono
  • il n'effectue pas de détection de plate-forme au moment de l'exécution, mais utilise à la place des informations codées en dur
    (voir le numéro 3032 de corefx pour plus de détails)

Vous pouvez épingler des fonctions non gérées spécifiques à la plate-forme, telles que uname()mais:

  • cela peut provoquer une erreur de segmentation sur des plates-formes inconnues
  • n'est pas autorisé dans certains projets

Donc, ma solution suggérée (voir le code ci-dessous) peut sembler sournoise au début, mais:

  • il utilise du code 100% géré
  • cela fonctionne en .NET, Mono et .NET Core
  • cela fonctionne comme un charme jusqu'à présent dans la bibliothèque 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
la source
1
Appréciez vos efforts. Souhaite qu'il puisse y avoir une certaine cohérence à l'avenir.
leppie
6
System.Runtime.InteropServices.RuntimeInformation devrait fonctionner correctement dans le .net complet maintenant (depuis novembre), donc cela semble être la "bonne" méthode acceptée maintenant. Pas sûr de mono, mais comme ils prennent du code directement à partir de .net maintenant qu'il est open source, ce n'est qu'une question de temps avant qu'il ne fonctionne là-bas, sinon déjà.
GrandOpener
1
Path.DirectorySeparatorChar Peut être utilisé pour déterminer s'il s'agit d'une machine Windows ou * nix.
kiran
Les InteropServices sont très étranges. Dans VStudio et Rider, j'obtiens parfois "Inconnu dans ce contexte" ou il compile. Aucune idée de la raison de cet échec ...
Slesa