Determinar o sistema operacional no .NET Core

118

Como posso determinar em qual sistema operacional meu aplicativo .NET Core está sendo executado? No passado, eu poderia usar Environment.OSVersion.

Qual é a forma atual de determinar se meu aplicativo está sendo executado no Mac ou Windows?

dknaack
fonte
stackoverflow.com/a/28664021/1009099 veja isto
Kovpaev Alexey
Não é realmente a resposta que eu estava procurando, mas encontrei sozinho.
dknaack
Consulte este artigo codepedia.info/…
Satinder singh

Respostas:

184

Método

System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform()

Possível Argumento

OSPlatform.Windows
OSPlatform.OSX
OSPlatform.Linux

Exemplo

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

Atualizar

Graças ao comentário de Oleksii Vynnychenko

Você pode obter o nome e a versão do sistema operacional como uma string usando

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

Por exemplo, osNameAndVersionseriaMicrosoft Windows 10.0.10586

dknaack
fonte
4
Você pode adicionar isso para obter mais informações sobre o sistema operacional, há outra propriedade nesse pacote: System.Runtime.InteropServices.RuntimeInformation.OSDescription- retorna a descrição do sistema operacional com a versão, etc.
Oleksii Vynnychenko
15
1 embora eu não goste desta resposta. Por que eles não podem apenas implementar System.Environment.OSVersion.Platformpara consistência?
leppie
2
Observe que as constantes não representam todos os sistemas operacionais com suporte. É possível testar outros sistemas operacionais, usando IsOSPlatform(OSPlatform.Create("FreeBSD"))se eles são suportados agora ou podem ser adicionados no futuro. No entanto, não está muito claro qual seria uma abordagem segura para quais strings passariam (por exemplo, maiúsculas e minúsculas são importantes ou "bsd"correspondem a ambos "FreeBSD"e "NetBSD"?). Veja a discussão sobre esse recurso aqui .
NightOwl888
37

System.Environment.OSVersion.Platform pode ser usado em .NET Framework e Mono completos, mas:

  • A detecção do Mac OS X quase nunca funcionou para mim no Mono
  • não é implementado no .NET Core

System.Runtime.InteropServices.RuntimeInformation pode ser usado no .NET Core, mas:

  • não está implementado em .NET Framework e Mono completos
  • ele não realiza detecção de plataforma em tempo de execução, mas usa informações codificadas em seu lugar
    (consulte o problema nº 3032 da corefx para obter mais detalhes)

Você pode identificar funções não gerenciadas específicas da plataforma, como uname():

  • pode causar falha de segmentação em plataformas desconhecidas
  • não é permitido em alguns projetos

Portanto, minha solução sugerida (veja o código abaixo) pode parecer tola no início, mas:

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
fonte
1
Agradeço seu esforço. Gostaria que houvesse alguma consistência no futuro.
leppie
6
System.Runtime.InteropServices.RuntimeInformation deve funcionar corretamente em .net completo agora (desde novembro), de modo que parece ser a forma "certa" aceita agora. Não tenho certeza sobre o mono, mas como eles estão pegando algum código direto do .net agora que é open source, é apenas uma questão de tempo antes que ele funcione lá, se já não estiver.
GrandOpener de
1
Path.DirectorySeparatorChar Pode ser usado para determinar se é uma máquina Windows ou * nix.
Kiran de
InteropServices são muito estranhos. No VStudio e no Rider, às vezes recebo "Desconhecido neste contexto" ou ele compila. Não
tenho