在系統維護過程中,為了方便分析應用程序錯誤,我們經常要確定用戶的環境,如操作系統的版本。為了快速准確地獲取版本信息,可以通過程序讀取(有的小白用戶可能不知道怎么查看系統版本)。一般獲取操作系統版本的方法有三種:
一、環境參數法
通過Environment即可獲取Version版本信息。
OperatingSystem os = Environment.OSVersion; Version ver = os.Version;
Version版本號分四段,其定義如下:
Major:主版本號;
Minor:次版本號;
Build:內部版本號;
Revision:修訂版本號。
版本號對應關系表:
此方法在Win10下獲取的值可能不是10,這是因為版本不兼容,解決方案是程序應用清單中增加配置:
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <application> <!-- Windows 10 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> <!-- Windows 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> </application> </compatibility>
二、注冊表法
通過獲取注冊存儲的信息來獲取操作系統版本號信息,位置在:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion
示例代碼如下:
/// <summary> /// 操作系統信息 /// </summary> public static class ComputerInfo { /// <summary> /// 操作系統名稱 /// </summary> public static string WinProductName { get { if (TryGetRegistryKey(@"SOFTWARE\Microsoft\WindowsNT\CurrentVersion", "ProductName", out var productName)) { return (string)productName; } return "未知"; } } /// <summary> /// 操作系統主要版本號 /// </summary> public static uint WinMajorVersion { get { if (TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentMajorVersionNumber", out var major)) { return (uint) major; } if (!TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentVersion", out var version)) return 0; var versionParts = ((string) version).Split('.'); if (versionParts.Length != 2) return 0; return uint.TryParse(versionParts[0], out var majorAsUInt) ? majorAsUInt : 0; } } /// <summary> /// 操作系統次要版本號 /// </summary> public static uint WinMinorVersion { get { if (TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentMinorVersionNumber", out var minor)) { return (uint) minor; } if (!TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentVersion", out var version)) return 0; var versionParts = ((string) version).Split('.'); if (versionParts.Length != 2) return 0; return uint.TryParse(versionParts[1], out var minorAsUInt) ? minorAsUInt : 0; } } /// <summary> /// 判斷是否為Server系統 /// </summary> public static uint IsServer { get { if (TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "InstallationType", out var installationType)) { return (uint) (installationType.Equals("Client") ? 0 : 1); } return 0; } } /// <summary> /// 獲取注冊表值 /// </summary> /// <param name="path">路徑</param> /// <param name="key">鍵</param> /// <param name="value">值</param> /// <returns>是否成功</returns> private static bool TryGetRegistryKey(string path, string key, out dynamic value) { value = null; try { using (var rk = Registry.LocalMachine.OpenSubKey(path)) { if (rk == null) return false; value = rk.GetValue(key); return value != null; } } catch { return false; } } }
三、底層API法(推薦)
使用RtlGetVersion或GetVersionEx來實現任何Windows系統版本號的讀取。
public static class VersionHelper { [SecurityCritical] [DllImport("ntdll.dll", SetLastError = true)] public static extern bool RtlGetVersion(ref OsVersionInfoEx versionInfo); [DllImport("kernel32.dll")] public static extern bool GetVersionEx([In, Out] OsVersionInfoEx versionInfo); /// <summary> /// 操作系統版本信息結構 /// </summary> [StructLayout(LayoutKind.Sequential)] public struct OsVersionInfoEx { //定義:https://docs.microsoft.com/zh-cn/windows-hardware/drivers/ddi/wdm/ns-wdm-_osversioninfoexw internal int OSVersionInfoSize; //對象結構的大小 internal int MajorVersion; //主要版本號 internal int MinorVersion; //次要版本號 internal int BuildNumber; //內部版本號 internal int PlatformId; //平台標識符 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] internal string CSDVersion; //補丁版本字符串,如Service Pack 3 internal ushort ServicePackMajor; //補丁版本的主要版本號,如Service Pack 3主要版本號為3 internal ushort ServicePackMinor; //補丁版本的次要版本號,如Service Pack 3次要版本號為0 internal short SuiteMask; //可用的產品套件,如VER_SUITE_SINGLEUSERTS表示支持遠程桌面 internal byte ProductType; //產品類型,如VER_NT_WORKSTATION表示Windows 2000 或更高版本專業版 internal byte Reserved; //保留供將來使用 } public static Version GetVersion() { var osVersionInfo = new OsVersionInfoEx { OSVersionInfoSize = Marshal.SizeOf(typeof(OsVersionInfoEx)) }; if (!RtlGetVersion(ref osVersionInfo)) { osVersionInfo = new OsVersionInfoEx { OSVersionInfoSize = Marshal.SizeOf(typeof(OsVersionInfoEx)) }; GetVersionEx(osVersionInfo); } var version = new Version( osVersionInfo.MajorVersion, osVersionInfo.MinorVersion, osVersionInfo.BuildNumber); return version; } }