sysinfo icon indicating copy to clipboard operation
sysinfo copied to clipboard

Windows 11 versioning incorrect

Open sethwheway opened this issue 3 years ago • 10 comments

When on Windows 11, functions such as long_os_version are returning what they would on Windows 10. It seems that the crate is pulling these values from registry (SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion) and the registry values are not updated when upgrading from W10 to W11. While I would consider it outside of the scope of the crate to fix strange Windows versioning quirks, according to a post on the Microsoft forums about this issue, they were told by a Windows dev that quering registry values for versioning was not the 'proper' way to get versioning info and the revelvant API calls should be used instead. I can understand if you do not want to deal with this behaviour and this will never be fixed, however I thought I would report the issue in case you were not aware of it and for anyone looking for information on why their versioning info seemed to be incorrect when running Windows 11

sethwheway avatar Dec 27 '21 13:12 sethwheway

No, it should work as expected. The problem being that I don't have a Windows 11. If someone with a Windows 11 could fix this issue, this would be very appreciated. :)

GuillaumeGomez avatar Dec 27 '21 14:12 GuillaumeGomez

I have an upgraded Win11 machine. I've tried all the WinAPIs including GetVersionExA() and GetProductInfo() and none of them work correctly - actually they produce just wrong and incorrect versions - for instance GetProductInfo which is supposed to be the best way, says my machine is "Windows 10 Enterprise Evaluation" which is nonsense - it is Win11 Pro. The only way I can see to do this correctly is to look at the build number (22000 and > for Win11) which seems to return correctly. I'm happy to create a pull request to hashmap a table of build numbers if you like?

oraclerob avatar Jan 31 '22 04:01 oraclerob

That would be very welcome!

GuillaumeGomez avatar Jan 31 '22 09:01 GuillaumeGomez

I looked into this and came to the conclusion that checking the version number is good enough. There are definately APIs that report the correct version somewhere. This powershell line does Get-WmiObject -Class Win32_OperatingSystem | Format-List -Property Caption report Windows 11, however I'm still trying to find the API this calls that does actually report the correct version

sethwheway avatar Jan 31 '22 10:01 sethwheway

I would be interested to see if there a definite WinAPI call that works i.e. I want to see "11" or "10" or "8.1" come back. My reading came to the conclusion that GetVersionExA() is deprecated and GetProductInfo should be the call. However, both are not suitable just to retrieve a version number and need post processing with logic and even that is more complicated and error prone. The build or kernel number is much more accurate and is documented in tables to match the major version number. More info here... https://docs.microsoft.com/en-us/windows/win32/sysinfo/version-helper-apis and here.. https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getproductinfo

oraclerob avatar Jan 31 '22 11:01 oraclerob

We can add a match on the builder/kernel number. But that will mean that when a new Windows version is released, we will need to update the code. It's fine by me but something to remember. :)

GuillaumeGomez avatar Feb 01 '22 19:02 GuillaumeGomez

The build numbers are in ranges for the the major OS version. So we would only need to update the code when Windows 12 gets released. I can't think of another way to do this accurately unless Microsoft release an API that actually works. I'm certainly not happy it's come to this hacky solution.

oraclerob avatar Feb 02 '22 00:02 oraclerob

It's fine. Anyone interested into sending a PR to do it?

GuillaumeGomez avatar Feb 02 '22 08:02 GuillaumeGomez

Just finishing another Rust project, I'm a novice but might be interested in creating a PR for you.

oraclerob avatar Feb 02 '22 14:02 oraclerob

No hurry then. Take your time. :)

GuillaumeGomez avatar Feb 02 '22 14:02 GuillaumeGomez

Hello! I researched several sources and came to the same conclusion. The easiest way to distinguish windows 11 from 10 is by looking into "CurrentBuildNumber, as mentioned above. Windows 11's build number starts from "22000", and 10's is from "10240" up to "19044" at present.

I made some simple changes and confirmed it goes as expected.

static WINDOWS_ELEVEN_BUILD_NUMBER: u32 = 22000;

impl System {
    fn is_windows_eleven(&self) -> bool {
        WINDOWS_ELEVEN_BUILD_NUMBER
            >= self
                .kernel_version()
                .unwrap_or_default()
                .parse()
                .unwrap_or(0)
    }
}

fn long_os_version(&self) -> Option<String> {
        if self.is_windows_eleven() {
            return get_reg_string_value(
                HKEY_LOCAL_MACHINE,
                "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
                "ProductName",
            )
            .map(|product_name| product_name.replace("10", "11"));
        }
        get_reg_string_value(
            HKEY_LOCAL_MACHINE,
            "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
            "ProductName",
        )
    }
let mut sys = System::new_all();
    sys.refresh_all(); 
    // Some("Windows")
    println!("{:?}", sys.name());
    // Some("Windows 11 Home")
    println!("{:?}", sys.long_os_version());
    // Some("11 (22000)")
    println!("{:?}", sys.os_version());

k0i avatar Aug 24 '22 03:08 k0i

@k0i Want to open a pull request with these changes? :)

GuillaumeGomez avatar Aug 24 '22 08:08 GuillaumeGomez

Thank you for your time GuillaumeGomez ! I'll give it a try!

k0i avatar Aug 24 '22 11:08 k0i

Thanks for this fix

sethwheway avatar Sep 21 '22 13:09 sethwheway