最可靠方法是组合使用RuntimeInformation.OSDescription解析和注册表CurrentBuildNumber读取。OSDescription无需清单且语义清晰,但需正则提取版本号;注册表值稳定不受运行时影响,但UWP/WinUI不可用,二者互补可提升准确率。

Environment.OSVersion.Version.Build 判断法(最常用但有坑)
直接读 Environment.OSVersion.Version.Build 是多数人第一反应,因为 Win10 的典型 build 是 19045,Win11 从 22000 起步。但这个值是否可靠,取决于你有没有配清单文件。
- 如果没加
app.manifest或里面<supportedos></supportedos>被注释了,.NET Framework 程序可能返回6.2(即 Win8),.NET Core/5+ 则通常能拿到真实 build,但仍有兼容层干扰风险 - 即使 build 是
22000,也得确认主版本是10——毕竟理论上未来 Win12 可能用11.x,但现在全是10.0.x - 示例判断逻辑:
var v = Environment.OSVersion.Version;<br>if (v.Major == 10 && v.Build >= 22000) { /* Win11 */ }<br>else if (v.Major == 10 && v.Build < 22000) { /* Win10 */ }
Registry 读取 CurrentBuildNumber(稳定、无需清单)
注册表路径 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion 下的 CurrentBuildNumber 是系统安装时写死的,不受应用清单影响,也不依赖 .NET 版本。
- 值类型是字符串,需转
int;若读取失败(权限不足或沙盒环境),要加 try/catch - 同时建议校验
CurrentMajorVersionNumber,它在 Win10/11 都是10,可防低版本 Windows 误判 - 注意:UWP/WinUI 应用默认无注册表读取权限,此法不适用
RuntimeInformation.OSDescription 解析(.NET Core 3.0+ 推荐)
System.Runtime.InteropServices.RuntimeInformation.OSDescription 返回类似 "Microsoft Windows 11 Enterprise v10.0.22631" 的字符串,比 OSVersion 更贴近用户看到的系统名。
- 不依赖清单,.NET 5+ 和大多数 .NET Core 版本都支持
- 解析时别硬拆空格,优先用正则匹配
\b\d+.\d+.\d+\b找出完整版本号,再取第三段(build)做比较 - 缺点是字符串格式非标准化,某些精简版或企业定制系统可能省略 “Windows 11”,只写 “Windows”,这时仍得 fallback 到 build 判断
IsWindows11OrGreater() API(.NET 5+ 官方推荐,但有限制)
OperatingSystem.IsWindows11OrGreater() 是微软封装好的判断函数,内部综合了注册表和系统能力检测,语义清晰、调用简单。
- 仅限 .NET 5 及以上,.NET Framework 或 .NET Core 3.1 不能用
- 它底层仍查
CurrentBuildNumber,所以和注册表法结论一致,但屏蔽了手动解析细节 - 如果你项目已升到 .NET 6/7/8,这是最省心的选择;否则别为它单独升级框架
Win11 的 build 分界线(22000)看似简单,但实际落地时,清单配置、运行时环境、部署目标(如容器、受限 AppContainer)、甚至杀毒软件拦截注册表访问,都可能让一个看似“稳”的判断突然失效。真正在意准确率的场景,建议组合两种方式:先用 OSDescription 快速判断,再用注册表 fallback 校验。


















