.NET 4.8 C#应用如何可靠获取Windows系统版本详细信息
C#/.NET 4.8 可靠Windows系统信息获取方案
你目前在用的核心逻辑已经是当前环境下最稳定的方案,只需要做少量鲁棒性优化即可适配未来Windows版本,无需额外调整核心流程。
核心逻辑说明
以下逻辑完全规避「版本谎言」问题,无需修改应用程序清单,所有用到的接口和注册表字段均为微软公开的长期支持项:
- 系统名称/SKU直接读取注册表
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion下的ProductName值,该字段从Windows XP到Windows 11均未变更,微软后续版本也会沿用;Windows 7及更早版本可额外拼接同路径下的CSDVersion值补全Service Pack信息。 - 半年频道版本标识优先读取同路径下的
DisplayVersion值(Windows 10 20H2及后续版本使用),不存在时降级读取ReleaseId值,完全覆盖所有Windows 10/11版本。 - 完整内部版本号通过P/Invoke调用
ntdll.dll的RtlGetVersion内核接口获取真实的主版本、次版本、Build号,无版本谎言问题;再读取同路径下的UBR值补全补丁修订号,最终拼接为完整版本号。
完整代码示例
using System; using System.Runtime.InteropServices; using Microsoft.Win32; public static class WindowsSystemInfo { [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private struct OSVERSIONINFOEX { public int dwOSVersionInfoSize; public int dwMajorVersion; public int dwMinorVersion; public int dwBuildNumber; public int dwPlatformId; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string szCSDVersion; public ushort wServicePackMajor; public ushort wServicePackMinor; public ushort wSuiteMask; public byte wProductType; public byte wReserved; } [DllImport("ntdll.dll", SetLastError = true)] private static extern int RtlGetVersion(ref OSVERSIONINFOEX lpVersionInformation); public static string GetFormattedSystemInfo() { string productName = "未知Windows版本"; string versionTag = string.Empty; int ubr = 0; // 读取注册表信息 using (var regKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", false)) { if (regKey != null) { productName = regKey.GetValue("ProductName") as string ?? productName; // 优先取DisplayVersion,降级取ReleaseId versionTag = regKey.GetValue("DisplayVersion") as string ?? regKey.GetValue("ReleaseId") as string ?? string.Empty; ubr = (int)(regKey.GetValue("UBR") ?? 0); // 拼接Windows 7的Service Pack信息 var csdVersion = regKey.GetValue("CSDVersion") as string; if (!string.IsNullOrEmpty(csdVersion)) { productName += $" {csdVersion}"; } } } // 调用内核接口获取真实版本号 var osInfo = new OSVERSIONINFOEX(); osInfo.dwOSVersionInfoSize = Marshal.SizeOf(osInfo); RtlGetVersion(ref osInfo); // 拼接完整内部版本号 string fullBuild = $"{osInfo.dwMajorVersion}.{osInfo.dwMinorVersion}.{osInfo.dwBuildNumber}"; if (ubr > 0) { fullBuild += $".{ubr}"; } // 返回要求格式的结果 return $"名称: {productName}、版本: {versionTag}、内部版本号: {fullBuild}"; } }
适配未来版本说明
- 不要硬编码版本号判断系统类型,直接使用
ProductName返回的内容即可,微软会在新版本系统中自动更新该字段值,无需后续修改代码适配。 - 上述所有接口均为微软官方文档中标注为可用于版本检测的稳定接口,除非Windows内核架构发生颠覆性变更,否则不会失效。
内容的提问来源于stack exchange,提问作者paulgutten
相关产品推荐
相关产品推荐

