Windows 8.1 -> GetVersion(Ex) deprecated -> let's fix it in Qt!
As you might have read, with Windows 8.1, the GetVersion(Ex) API has been deprecated and will now pretend to be Windows 8.0, even when running under Windows 8.1. Microsoft says that is to prevent compatibility problems. I think it is a horrible idea to break the API in that way. It is also the reason why Qt happily detects Windows 8.1 as Windows 8.0 (it should detect an "unknown" operating system, since there is no 8.1 detection yet, but it doesn't, because of the M$ hack!)
Anyway, it seems we must now use VerifyVersionInfo() to determine the real Windows version.
Here is my attempt to write a getRealOsVersion() function:
-link removed- (see post below!)
Output on Windows 8.1:
@Windows Version: 6.2
Real Windows Version: 6.3@
I hope this (or a similar solution) can be used into Qt to fix version detection :)
You should talk about this on the development mailing list and/or submit a patch through gerrit. Posting here will likely get your suggestion lost since the forum is generally not followed by Qt's maintainers/developers.
Okay, I will try to write up a patch.
In the meantime, here is an improved (faster) version:
Just my opinion - it is the worst kind of API change M$ could come up with. I would love to see their rationale behind this.
Their "rationale" is that (apparently) some applications out there use GetVersionEx() to check for a specific "compatible" version of Windows (or a set of "compatible" Windows versions). These applications refuse to run, if the installed version differs from the expected version - even if the installed version is actually newer than the expected version. So if, for example, the application was written to run on NT v6.2 (Windows 8) and GetVersionEx() returns NT v6.3 (Windows 8.1) now, the application stops working.
Obviously this a bug in the specific application and should be fixed in that application! Applications should never refuse to run on future Windows versions. It's reasonable to refuse running on old versions which are known to be incompatible to the application. But most of the time it is better to check for the availability of the required feature at runtime, rather than making assumptions about the availability based solely on version numbers.
Anyway, even if we have such "broken" application, we could still make it work under Windows 8.1 by using the compatibility settings - which have been available since Windows XP. But apparently Microsoft wants to avoid reports about "compatibility issues" in Windows 8.1 by all means. There has been enough "bad press" about Windows 8 already ;-) So even broken applications have to run "out of the box" now, even if that requires ugly hacks.
Result: Under Windows 8.1 (v6.3) applications are running in compatibility mode for "Windows 8" (v6.2) by default - and no way to turn that off...
<<shivers>> This is an entirely new kind of bad. I mean this is on the level of what IE and all its compatibility and quirks modes did to the webbed world.
I mean look at the size of the function you had to write for a damn number (thx btw). Usually I can cope to some degree with MS guys ideas but this is ridiculous.
bq. In Windows 8.1, the GetVersion(Ex) APIs have been deprecated. That means that while you can still call the APIs, if your app does not specifically target Windows 8.1, you will get Windows 8 versioning (18.104.22.168).
To adequately target Windows 8.1 you have a new arcane incantation to add the to application manifest. Having done that the implication is that GetVersionEx() will return 8.1 versioning.
Adding a manifest doesn't help at all. Here is why:
By adding a compatibility manifest to my application and declaring my application compatible to Windows 8.1 (v6.3), I can get GetVersionEx() report Windows 8.1 correctly. Otherwise it pretends to be Windows 8.0 (v6.2).
BUT: I cannot add manifests to my application for future versions of Windows - and that wouldn't make any sense. So, even if I add a manifest for Windows 8.1 today, my application will start getting invalid version info from GetVersionEx() with the next version of Windows, e.g. Windows 8.3 or 9.0.
Obviously, when I call an API like GetVersionEx() or QSystemInfo::windowsVersion() at runtime, I want to know which Windows version we are actually running on - not what version my application is compatible to! I already know what Windows version my application is compatible, at compile-time. No need to ask the OS at run-time ;-)
In other words, GetVersionEx() has been changed to report whatever has been declared the maximum supported version in the application's manifest. This makes GetVersionEx() pretty much a NOP operation on Windows 8.1. I could as well declare the result as a MACRO at compile-time :-P
I didn't claim it was sane, just that without modifying Qt you have an option you can use now. I agree that Qt will have to adapt so that is does not get lied to.
This behaviour on Microsoft's part is not new: Windows routinely lies to legacy applications about the write-ability of certain protected directories (the virtual store) and the available screen real-estate (display scaling).