Getting Windows version 23H2 from Win32_OperatingSystem

50 views Asked by At

Code:

std::map<CString, CString> mapWindowsVersions
{
    { L"22631", L"23H2" },
    { L"22621", L"22H2" },
    { L"22000", L"21H2" },
    { L"19044", L"21H2" },
    { L"19043", L"21H1" },
    { L"19042", L"20H2" },
    { L"19041", L"2004" },
    { L"18363", L"1909" },
    { L"18362", L"1903" },
    { L"17763", L"1809" },
    { L"17134", L"1803" },
    { L"16299", L"1709" }
};
VARIANT vtProp{};
hres = pclsObj->Get(L"BuildNumber", 0, &vtProp, 0, 0);
strSystemInfo.AppendFormat(L"  Build Number: %s\r\n", mapWindowsVersions[vtProp.bstrVal]);
VariantClear(&vtProp);

This works., I gleaned release descriptions from here. But is there a built-in way to get this description, eg: 23H2?

2

There are 2 answers

0
Dai On BEST ANSWER

I don't know the answer off-the-top-of-my-head, but I know where to start looking: winver.exe.

Here's my About Windows dialog, which dutifully displays the "Version 22H2" string you're after:

enter image description here

  • Firing up winver.exe in WinDbg or Ghidra or whathaveyou shows that winver.exe just calls into Shell32.dll!ShellAboutW to do all its actual work.
  • ...which in-turn sets-up a Dialog Resource using the (non-exported) function AboutDlgProc to drive the About Windows dialog.
  • ...which calls _InitAboutDlg to load the data (strings, text, etc) into the Dialog's labels/placeholders.
  • ...which opens the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion registry key and then extracts values based on some arbitrary business rules:
    • Apparently there's a (WinRT? C++/CX?) API called EnableH2UIVersioning which controls whether the "22H2"-style release name will be displayed or not. When this is true then the "22H2" string comes from HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DisplayVersion, otherwise it uses HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ReleaseId.
  • On my machine, both DisplayVersion and ReleaseId are present, but ReleaseId contains the incorrect/old value of "2009" - which means that ReleaseId cannot be trusted if present.
6
Andrew Truckle On

Based on the suggestions in the comments I have come up with the following solution:

hres = pclsObj->Get(L"Caption", 0, &vtProp, 0, 0);
strSystemInfo.AppendFormat(L"  Edition: %s\r\n", vtProp.bstrVal);
VariantClear(&vtProp);

hres = pclsObj->Get(L"Version", 0, &vtProp, 0, 0);
strSystemInfo.AppendFormat(L"  Version: %s\r\n", vtProp.bstrVal);
VariantClear(&vtProp);

hres = pclsObj->Get(L"BuildNumber", 0, &vtProp, 0, 0);
strSystemInfo.AppendFormat(L"  Version Build Number: %s\r\n", vtProp.bstrVal);

CSettingsStore store(true, true);
if (store.Open(L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"))
{
    CString strDisplayVersion;
    const auto buildNumber = _ttoi(CString(vtProp.bstrVal));
    if (buildNumber > 19041)
    {
        if (store.Read(L"DisplayVersion", strDisplayVersion))
        {
            strSystemInfo.AppendFormat(L"  Version Codename: %s\r\n", strDisplayVersion);
        }
    }
    else
    {
        if (store.Read(L"ReleaseId", strDisplayVersion))
        {
            strSystemInfo.AppendFormat(L"  Version Codename: %s\r\n", strDisplayVersion);
        }
    }
}
VariantClear(&vtProp);

Which displays the following output on my About window:

Edition: Microsoft Windows 11 Home
Version: 10.0.22631
Version Build Number: 22631
Version Codename: 23H2