Tentukan Sistem Operasi di .NET Core

118

Bagaimana cara menentukan sistem operasi mana yang menjalankan aplikasi .NET Core saya? Di masa lalu saya bisa menggunakan Environment.OSVersion.

Apa cara saat ini untuk menentukan apakah aplikasi saya berjalan di Mac atau Windows?

dknaack
sumber
stackoverflow.com/a/28664021/1009099 lihat ini
Kovpaev Alexey
Bukan jawaban yang saya cari, tetapi saya menemukannya sendiri.
dknaack
Lihat artikel ini codepedia.info/…
Satinder singh

Jawaban:

184

metode

System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform()

Argumen yang Mungkin

OSPlatform.Windows
OSPlatform.OSX
OSPlatform.Linux

Contoh

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

Memperbarui

Terima kasih atas komentar Oleksii Vynnychenko

Anda bisa mendapatkan nama dan versi sistem operasi sebagai string menggunakan

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

Misalnya osNameAndVersionakanMicrosoft Windows 10.0.10586

dknaack
sumber
4
Anda dapat menambahkan itu untuk mendapatkan lebih banyak informasi tentang OS, ada properti lain dalam paket itu: System.Runtime.InteropServices.RuntimeInformation.OSDescription- mengembalikan deskripsi OS dengan versi, dll.
Oleksii Vynnychenko
15
+1 meskipun saya tidak suka jawaban ini. Mengapa mereka tidak bisa menerapkan hanya System.Environment.OSVersion.Platformuntuk konsistensi?
leppie
2
Perhatikan bahwa konstanta tidak mewakili semua OS yang didukung. Anda dapat menyelidiki OS lain dengan menggunakan IsOSPlatform(OSPlatform.Create("FreeBSD"))apakah mereka didukung sekarang atau mungkin ditambahkan di masa mendatang. Namun, tidak terlalu jelas pendekatan apa yang aman untuk string apa yang akan diteruskan (misalnya, apakah kasus penting, atau apakah "bsd"cocok dengan keduanya "FreeBSD"dan "NetBSD"?). Lihat diskusi tentang fitur ini di sini .
NightOwl888
37

System.Environment.OSVersion.Platform dapat digunakan secara penuh .NET Framework dan Mono tetapi:

  • Deteksi Mac OS X hampir tidak pernah berhasil untuk saya di bawah Mono
  • itu tidak diimplementasikan di .NET Core

System.Runtime.InteropServices.RuntimeInformation dapat digunakan di .NET Core tetapi:

  • itu tidak diimplementasikan secara penuh .NET Framework dan Mono
  • itu tidak melakukan deteksi platform dalam runtime tetapi menggunakan informasi hardcode sebagai gantinya
    (lihat masalah corefx # 3032 untuk lebih jelasnya)

Anda dapat melakukan pinvoke fungsi tidak terkelola khusus platform seperti uname()tetapi:

  • itu dapat menyebabkan kesalahan segmentasi pada platform yang tidak diketahui
  • tidak diperbolehkan di beberapa proyek

Jadi solusi yang saya sarankan (lihat kode di bawah) mungkin terlihat konyol pada awalnya tetapi:

  • itu menggunakan 100% kode yang dikelola
  • ini bekerja di .NET, Mono dan .NET Core
  • bekerja seperti pesona sejauh ini di perpustakaan 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
sumber
1
Hargai usaha Anda. Semoga ada konsistensi di masa depan.
leppie
6
System.Runtime.InteropServices.RuntimeInformation seharusnya bekerja dengan benar dalam .net penuh sekarang (sejak November), jadi itu tampaknya menjadi cara yang "benar" diterima sekarang. Tidak yakin tentang mono, tetapi karena mereka mengambil beberapa kode langsung dari .net sekarang menjadi open source, hanya masalah waktu sebelum itu berfungsi di sana, jika belum.
GrandOpener
1
Path.DirectorySeparatorChar Dapat digunakan untuk menentukan apakah itu mesin windows atau * nix.
kiran
InteropServices sangat aneh. Dalam VStudio dan Rider, saya terkadang mendapatkan "Tidak diketahui dalam konteks ini" atau dikompilasi. Tidak tahu tentang alasan kegagalan ini ...
Slesa