C#中獲取操作系統版本


在系統維護過程中,為了方便分析應用程序錯誤,我們經常要確定用戶的環境,如操作系統的版本。為了快速准確地獲取版本信息,可以通過程序讀取(有的小白用戶可能不知道怎么查看系統版本)。一般獲取操作系統版本的方法有三種:

一、環境參數法

通過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;
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM