Determinar el sistema operativo en .NET Core


118

¿Cómo puedo determinar en qué sistema operativo se ejecuta mi aplicación .NET Core? En el pasado me vendría bien Environment.OSVersion.

¿Cuál es la forma actual de determinar si mi aplicación se ejecuta en Mac o Windows?



No es realmente la respuesta que estaba buscando, pero la encontré yo mismo.
dknaack

Consulte este artículo codepedia.info/…
Satinder singh

Respuestas:


184

Método

System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform()

Posible argumento

OSPlatform.Windows
OSPlatform.OSX
OSPlatform.Linux

Ejemplo

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

Actualizar

Gracias al comentario de Oleksii Vynnychenko

Puede obtener el nombre y la versión del sistema operativo como una cadena usando

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

Por ejemplo osNameAndVersion, seríaMicrosoft Windows 10.0.10586


4
Puede agregar eso para obtener más información sobre el sistema operativo, hay otra propiedad en ese paquete: System.Runtime.InteropServices.RuntimeInformation.OSDescription- devuelve la descripción del sistema operativo con la versión, etc.
Oleksii Vynnychenko

15
+1 aunque no me gusta esta respuesta. ¿Por qué no pueden simplemente implementar System.Environment.OSVersion.Platformpor coherencia?
leppie

2
Tenga en cuenta que las constantes no representan todos los sistemas operativos compatibles. Es posible buscar otros sistemas operativos utilizando IsOSPlatform(OSPlatform.Create("FreeBSD"))si son compatibles ahora o si se pueden agregar en el futuro. Sin embargo, no está muy claro cuál sería un enfoque seguro para qué cadenas pasar (por ejemplo, ¿importa el caso o "bsd"coincide con ambos "FreeBSD"y "NetBSD"?). Vea la discusión sobre esta característica aquí .
NightOwl888

37

System.Environment.OSVersion.Platform se puede utilizar en .NET Framework y Mono completos, pero:

  • La detección de Mac OS X casi nunca me funcionó en Mono
  • no está implementado en .NET Core

System.Runtime.InteropServices.RuntimeInformation se puede usar en .NET Core pero:

  • no está implementado en su totalidad .NET Framework y Mono
  • no realiza la detección de la plataforma en tiempo de ejecución, sino que utiliza información codificada
    (consulte el número 3032 de corefx para obtener más detalles)

Puede invocar funciones no administradas específicas de la plataforma, como uname()pero:

  • puede causar fallas de segmentación en plataformas desconocidas
  • no está permitido en algunos proyectos

Entonces, mi solución sugerida (ver código a continuación) puede parecer astuta al principio, pero:

  • utiliza código 100% administrado
  • funciona en .NET, Mono y .NET Core
  • funciona como un encanto hasta ahora en la biblioteca 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
Aprecie su esfuerzo. Ojalá haya algo de coherencia en el futuro.
leppie

6
System.Runtime.InteropServices.RuntimeInformation debería funcionar correctamente en .net completo ahora (desde noviembre), por lo que parece ser la forma "correcta" aceptada ahora. No estoy seguro acerca de mono, pero dado que están tomando algo de código directamente de .net ahora que es de código abierto, es solo cuestión de tiempo antes de que funcione allí, si no es que ya.
GrandOpener

1
Path.DirectorySeparatorChar Puede usarse para determinar si es una máquina con Windows o * nix.
Kiran

Los InteropServices son muy extraños. Dentro de VStudio y Rider, a veces obtengo "Desconocido en este contexto" o se compila. No tengo idea de la razón de esta falla ...
Slesa
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.