有没有官方方法可以检测Windows 11?

15
以下问题包含了检测系统是否运行Windows 10或Windows 11的各种方法: 然而,它们都似乎有点“hackish”和脆弱:检查文件版本、构建号、API可用性等。由于Windows 11的发布即将到来(预计于10月5日),软件供应商没有太多时间准备。因此,我的问题是: 如果您有合法的理由¹需要知道是否支持Windows 11,Microsoft是否已经发布了官方推荐的方法供软件开发者使用?
¹ 我知道许多程序“认为”它们需要检查操作系统版本号,但实际上它们只应关注所需功能的可用性。我完全支持这一点。然而,有些情况确实存在合法的用例(例如系统管理或软件清单工具),我请您假定这是一个合法用例的目的。 PS:本问题故意不限制于特定技术;我认为任何官方支持的解决方案(使用WinAPI、WMI、COM、.NET等)都是有效答案。

++,双倍投票。要求它成为官方的方式有很多种,有些方法需要更多时间,而其他方法则较为简便。 - undefined
6个回答

8
在 Microsoft Q&A 上,关于 "Windows 11 build ver is still 10.0.22000.194" 的问题帖子已经收到了两位微软员工的回复。在被采纳的答案中,其中之一表示:

至少目前来说,OS版本号22000是区分Windows 10和Windows 11的标准。

另外,在答案下方的评论中,另一名员工补充道:

这是正确的。任何高于10.0.22000.0的版本都是Win 11,低于此版本则为Win 10。

这表明,在2021年10月公开发布Windows 11一周后,微软尚未发布官方的软件开发人员建议。除非情况有变化,22000版本号似乎是你应该依赖的标准,以区分Windows 10和11。

1
这似乎不再正确 - 我看到的 Windows 11 构建字符串小于 22000,为 6.2.9200.0。 - David
2
@David:那是因为GetVersion(Ex)在欺骗你。v6.2是Windows 8。 - Heinzi
@Heinzi 有比 GetVersion(Ex) 更好的调用吗? - David
1
@David:RtlGetVersion似乎更准确,请参见https://dev59.com/0VwY5IYBdhLWcg3w37CG。就我个人而言,我会查询注册表https://dev59.com/LZjga4cB1Zd3GeqPFh08。 - Heinzi

2

最简单的方法是获取Kernel32.dll的版本,如果主要版本是10且构建版本>= 22000,则表示您使用的是Windows 11。这种方法没有任何“黑客”行为。

这里是我的代码: 如何在Windows 11中查找Windows产品名称?


2
约翰-亨的答案是一个很好的开始。不幸的是,微软在2022年9月发布了Windows 11的22H2更新,构建号为22621,使事情变得更加复杂。
你可以像Elmue建议的那样简单地使用“>=22000”,但这可能会在微软引入其他Windows服务器和客户端版本时出现问题。例如,在Windows 10的生命周期内,其构建号从10240到19045不等,多个Windows Server版本(2016、2019)落在该范围的中间。
如果你想处理Windows服务器和客户端版本,你需要使用一个查找表而不是一个简单的范围。我正在使用维基百科的Windows Client VersionsWindows Server Versions列表来维护一个“构建号到显示名称”的字典。如果我在字典中找不到当前的构建号,我就会回退到报告的操作系统版本(通常为10)。缺点是我必须记住更新字典,随着新的Windows版本发布,但这对于准确的操作系统识别来说是值得的。
private static readonly Dictionary<int, string> ModernWindowsBuildNumbers = new()
{
    // https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions
    [22000] = "Windows 11 21H2",
    [22621] = "Windows 11 22H2",

    // https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions#Server_versions
    [14393] = "Windows Server 2016",
    [17763] = "Windows Server 2019",
    [20348] = "Windows Server 2022",
};

string kernel32 = Environment.ExpandEnvironmentVariables(@"%SystemRoot%\System32\Kernel32.dll");
int buildNumber = FileVersionInfo.GetVersionInfo(kernel32).ProductBuildPart;
if (!ModernWindowsBuildNumbers.TryGetValue(buildNumber, out string displayName))
{
    // Report ProductName from registry instead.
    // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion
}

作为比注册表ProductName更好的备选方案,您可以报告Win32_OperatingSystem中的WMI Caption,如MacTwistie提到的那样。在我的系统上,它返回“Windows 11 Pro”。您可以使用ManagementObjectSearcher在.NET中运行WMI查询。 - Bill Menees

1
这个单行命令怎么样?在PowerShell中操作会更容易。
FOR /F "tokens=1,2,3 delims= " %%A IN ('wmic os get Caption') DO IF %%B EQU Windows set WVer=%%B %%C

这将返回"Windows 10"或"Windows 11"

如果您想要完整版本,例如:PRO / Education等,则可以扩展它。

FOR /F "tokens=1,2,3,4 delims= " %%A IN ('wmic os get Caption') DO IF %%B EQU Windows set WVer=%%B %%C %%D

干杯


1
Windows 11的架构基本上仍然使用Windows 10。许多来自Windows 10的剩余文件和系统仍然存在,例如错误命名的更新名称。 Windows 11仍然使用Windows 10版本号。虽然命令提示符已经过时,但它仍然是所有Windows系统的核心系统。因此,我制作了一个小工具,可以使用systeminfo检测它(很慢)。
参考链接:https://www.lifewire.com/windows-version-numbers-2625171
systeminfo | findstr /i /c:"windows 11" > nul && {code here for windows 11} || {code here for not windows 11}

我知道这可能不是你要找的解决方案,而且在现代应用程序中实施批处理脚本很困难,但我很乐意帮助你!


-1

也许我们可以使用以下代码:

auto fnWindows11OrGreater = []() -> bool {
    OSVERSIONINFOEX osvi;
    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    osvi.dwMajorVersion = 10;
    osvi.dwMinorVersion = 0;
    osvi.dwBuildNumber = 22000;
    DWORDLONG dwlConditionMask = 0;
    VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_EQUAL);
    VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_EQUAL);
    VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL);
    bool cond1 = VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER, dwlConditionMask);

    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    osvi.dwMajorVersion = 10;
    osvi.dwMinorVersion = 0;
    osvi.dwBuildNumber = 0;
    dwlConditionMask = 0;
    VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_EQUAL);
    VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER);
    VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL);
    bool cond2 = VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER, dwlConditionMask);

    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    osvi.dwMajorVersion = 10;
    osvi.dwMinorVersion = 0;
    osvi.dwBuildNumber = 0;
    dwlConditionMask = 0;
    VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER);
    VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
    VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL);
    bool cond3 = VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER, dwlConditionMask);

    return cond1 || cond2  || cond3;
};

您的回答目前写得不够清楚。请进行[编辑]以添加更多细节,帮助其他人了解如何解决问题。您可以在帮助中心找到有关编写良好答案的更多信息。 - Community
VerifyVersionInfo:此功能已在Windows 10中被弃用。 - Simpleton
VerifyVersionInfo: 此功能已在Windows 10中被弃用。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接