简体   繁体   English

正确检测 Windows 11

[英]Detecting Windows 11 properly

I'm a developper from the FOSS game 0 AD ( https://play0ad.com ) and I recently realised that our detection of the Windows version was failing for Windows 11, just like it did between Windows 8.1 and Windows 10.我是 FOSS 游戏 0 AD ( https://play0ad.com ) 的开发人员,我最近意识到我们对 Windows 11 的 Windows 版本的检测失败,就像在 Windows 8.1 和 Windows 10 之间一样。

It reports Windows 10.0.22000 which is technically the correct version, but we'd like it to report Windows 11 instead.它报告 Windows 10.0.22000,这在技术上是正确的版本,但我们希望它报告 Windows 11。

Here is the current code we use这是我们当前使用的代码

We're stuck with the Windows 7 SDK for compatibility reasons.出于兼容性原因,我们坚持使用 Windows 7 SDK。

Easy solution would be to replace简单的解决方案是更换

    if (osInfo.dwMajorVersion >= 10)
    {
        stream << "Win" << osInfo.dwMajorVersion;
    }

by经过

    if (osInfo.dwMajorVersion >= 10)
    {
        if (osInfo.dwMinorVersion > 22000)
            stream << "Win" << 11;
        else
            stream << "Win" << osInfo.dwMajorVersion;
    }

Is there a more robust/future proof solution.是否有更强大/面向未来的解决方案。

Thanks in advance!提前致谢!

I'm not sure if this will work, but can you give this code a try?我不确定这是否可行,但是您可以尝试一下此代码吗? It uses the sysinfoapi.h file.它使用 sysinfoapi.h 文件。 According to the docs, it only works on Windows though.根据文档,它只适用于 Windows。

#include <iostream>
#include <sysinfoapi.h>

void print_os_info()
{
    OSVERSIONINFOEX info;
    ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
    info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

    GetVersionEx((LPOSVERSIONINFO)&info);

    printf("Windows version: %u.%u\n", info.dwMajorVersion, info.dwMinorVersion);
}

int main()
{
    print_os_info();
}

EDIT: Apparently applications not manifested for Windows 8.1 or Windows 10 will return the Windows 8 OS version value (6.2) according the the sysinfoapi.h docs \\编辑:显然,未针对 Windows 8.1 或 Windows 10 显示的应用程序将根据sysinfoapi.h 文档返回 Windows 8 操作系统版本值 (6.2)

EDIT AGAIN: I tried using a $(Filename).exe.manifest file with the contents再次编辑:我尝试使用带有内容的 $(Filename).exe.manifest 文件

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
    <assemblyIdentity
        type="win32"
        name="Contoso.ExampleApplication.ExampleBinary"
        version="1.2.3.4"
        processorArchitecture="x86"
    />
    <description>Contoso Example Application</description>
    <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
        <application>
            <!-- Windows 10 and Windows 11 -->
            <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
            <!-- Windows 8.1 -->
            <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
            <!-- Windows 8 -->
            <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
            <!-- Windows 7 -->
            <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
            <!-- Windows Vista -->
            <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> 
        </application>
    </compatibility>
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
        <security>
            <requestedPrivileges>
                <!--
                  UAC settings:
                  - app should run at same integrity level as calling process
                  - app does not need to manipulate windows belonging to
                    higher-integrity-level processes
                  -->
                <requestedExecutionLevel
                    level="asInvoker"
                    uiAccess="false"
                />   
            </requestedPrivileges>
        </security>
    </trustInfo>
</assembly>

Which for me worked and made it print out Windows 10.0 instead of 6.2哪个对我有用并使它打印出 Windows 10.0 而不是 6.2
Sources: Manifest File , sysinfoapi.h来源: 清单文件sysinfoapi.h

Except the very weak, as for me, solution of considering Windows 10 build greater than 22000 as Windows 11, the only solution i found, which is actually working, is除了非常弱的解决方案,对我而言,将 Windows 10 构建大于 22000 作为 Windows 11 的解决方案,我发现的唯一实际可行的解决方案是

The WMIs Win32_OperatingSystem class - Caption property. WMIs Win32_OperatingSystem class - Caption属性。

On my dev Win10 machine it gives the following string: Microsoft Windows 10 Pro在我的开发 Win10 机器上,它提供以下字符串: Microsoft Windows 10 Pro

On my another dev machine, with Win11 installed, the same function gives: Microsoft Windows 11 Pro在我的另一台安装了 Win11 的开发机器上,同样的功能提供: Microsoft Windows 11 Pro

The difference is in string values - 10 vs 11 - but this is at least something far better than "build greater than" solution.区别在于字符串值 - 10 vs 11 - 但这至少比“构建大于”解决方案要好得多。

C# and C++ - works well. C# 和 C++ - 运行良好。

I am able to retrieve the version number properly.我能够正确检索版本号。 Copying my code below.在下面复制我的代码。 Using windows.h should work instead of sysinfoapi.h使用 windows.h 应该可以代替 sysinfoapi.h

#include<windows.h>
#include<stdio.h>
int main() {
     OSVERSIONINFOEX info;
     ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
     info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
     GetVersionEx((LPOSVERSIONINFO)&info);
     printf("Windows version: %u.%u\n", info.dwMajorVersion, info.dwMinorVersion);
}

Alternate way to read version number is to use GetProcAddress .读取版本号的另一种方法是使用GetProcAddress 'GetProcAddress' returns the address of specified DLL function. 'GetProcAddress' 返回指定 DLL 函数的地址。

#include<iostream>
#include<string>
#include <windows.h>
using namespace std;
void main() {
   int osver= 0.0;
   NTSTATUS(WINAPI *RtlGetVersion)(LPOSVERSIONINFOEXW);
   OSVERSIONINFOEXW osInfo;
   *(FARPROC*)&RtlGetVersion = GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion");    
     if (NULL != RtlGetVersion) {
            osInfo.dwOSVersionInfoSize = sizeof(osInfo);
            RtlGetVersion(&osInfo);
            osver = osInfo.dwMajorVersion;
      }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM