กำหนดระบบปฏิบัติการใน. NET Core


118

ฉันจะทราบได้อย่างไรว่าแอป. NET Core ของฉันกำลังทำงานบนระบบปฏิบัติการใด ในอดีตฉันสามารถใช้Environment.OSVersion.

วิธีปัจจุบันในการตรวจสอบว่าแอปของฉันทำงานบน Mac หรือ Windows คืออะไร



ไม่ใช่คำตอบที่ฉันกำลังมองหา แต่ค้นพบด้วยตัวเอง
dknaack

อ้างอิงบทความนี้ codepedia.info/…
Satinder singh

คำตอบ:


184

วิธี

System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform()

อาร์กิวเมนต์ที่เป็นไปได้

OSPlatform.Windows
OSPlatform.OSX
OSPlatform.Linux

ตัวอย่าง

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

ปรับปรุง

ขอบคุณความคิดเห็นโดย Oleksii Vynnychenko

คุณสามารถรับชื่อระบบปฏิบัติการและเวอร์ชันเป็นสตริงโดยใช้

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

เช่นosNameAndVersionจะเป็นMicrosoft Windows 10.0.10586


4
คุณสามารถเพิ่มสิ่งนั้นเพื่อรับข้อมูลเพิ่มเติมเกี่ยวกับ OS มีคุณสมบัติอื่นในแพ็คเกจนั้น: System.Runtime.InteropServices.RuntimeInformation.OSDescription- ส่งคืนคำอธิบายของระบบปฏิบัติการพร้อมเวอร์ชัน ฯลฯ
Oleksii Vynnychenko

15
+1 แม้ว่าฉันจะไม่ชอบคำตอบนี้ ทำไมพวกเขาไม่สามารถใช้System.Environment.OSVersion.Platformเพื่อความสม่ำเสมอได้?
leppie

2
โปรดทราบว่าค่าคงที่ไม่ได้แสดงถึง OS ที่รองรับทั้งหมด เป็นไปได้ที่จะตรวจสอบ OS อื่น ๆ โดยใช้IsOSPlatform(OSPlatform.Create("FreeBSD"))ว่ารองรับตอนนี้หรืออาจจะเพิ่มในอนาคต อย่างไรก็ตามยังไม่ชัดเจนว่าแนวทางที่ปลอดภัยคืออะไรสำหรับสตริงที่จะส่งผ่าน (เช่นกรณีมีความสำคัญหรือ"bsd"ตรงกับทั้งสอง"FreeBSD"และ"NetBSD"?) ดูการอภิปรายเกี่ยวกับคุณลักษณะนี้ที่นี่
NightOwl888

37

System.Environment.OSVersion.Platform สามารถใช้งานได้เต็มรูปแบบ. NET Framework และ Mono แต่:

  • การตรวจจับ Mac OS X แทบไม่เคยทำงานสำหรับฉันภายใต้ Mono
  • ไม่มีการใช้งานใน. NET Core

System.Runtime.InteropServices.RuntimeInformation สามารถใช้ได้ใน. NET Core แต่:

  • ไม่ได้นำไปใช้ใน. NET Framework และ Mono แบบเต็ม
  • ไม่ทำการตรวจจับแพลตฟอร์มในรันไทม์ แต่ใช้ข้อมูลฮาร์ดโค้ดแทน
    (ดูcorefx ฉบับ # 3032สำหรับรายละเอียดเพิ่มเติม)

คุณสามารถตรึงฟังก์ชั่นที่ไม่มีการจัดการเฉพาะแพลตฟอร์มเช่นuname()but:

  • อาจทำให้เกิดข้อผิดพลาดในการแบ่งส่วนบนแพลตฟอร์มที่ไม่รู้จัก
  • ไม่อนุญาตในบางโครงการ

ดังนั้นวิธีแก้ปัญหาที่ฉันแนะนำ (ดูรหัสร้อง) ในตอนแรกอาจดูไร้สาระ แต่:

  • ใช้รหัสที่มีการจัดการ 100%
  • ใช้งานได้ใน. NET, Mono และ. NET Core
  • มันใช้งานได้อย่างมีเสน่ห์จนถึงตอนนี้ในไลบรารี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
ขอขอบคุณสำหรับความพยายามของคุณ หวังว่าจะมีความสม่ำเสมอในอนาคต
leppie

6
System.Runtime.InteropServices.RuntimeInformation ควรทำงานได้อย่างถูกต้องใน. net เต็มรูปแบบในขณะนี้ (ตั้งแต่เดือนพฤศจิกายน) ดังนั้นตอนนี้ดูเหมือนว่าจะเป็นวิธีที่ "ถูกต้อง" ไม่แน่ใจเกี่ยวกับโมโน แต่เนื่องจากพวกเขากำลังรับโค้ดโดยตรงจาก. net ซึ่งตอนนี้มันเป็นโอเพ่นซอร์สจึงต้องใช้เวลาเพียงไม่นานก่อนที่มันจะทำงานที่นั่นหากยังไม่ได้ทำ
GrandOpener

1
Path.DirectorySeparatorChar สามารถใช้เพื่อตรวจสอบว่าเป็นเครื่อง windows หรือ * nix
kiran

InteropServices แปลกมาก ภายใน VStudio และ Rider บางครั้งฉันได้รับ "Unknown ในบริบทนี้" หรือคอมไพล์ ไม่รู้สาเหตุของความล้มเหลวนี้ ...
Slesa
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.