In our installer we're using GetVersionEx with OSVERSIONINFOEX structure to obtain Windows version.
According to the MSDN the expected return values for Windows 10 should be dwMajorVersion=6, dwMinorVersion=4.
In the build 9841 it works as expected.
But in build 9926 we got dwMajorVersion=10, dwMinorVersion=0.
Please advise how to get Windows version in a proper way or what should be return values for final Windows 10 release. Also we need to know the same information for new server platform.
what is the version checking for ? it is not like Microsoft has released any new API for Windows 10.
And you should move away from version checking. There is no law says Microsoft can't backport a feature to an older version of Windows (GDI+, IE, WIC etc), or the user/the EU antitrust agencies can't add/remove Windows features/roles. If you want to check whether something exists, check for its existence.
Visual C++ MVP
- Edited by Sheng Jiang 蒋晟MVP Monday, February 02, 2015 7:07 PM
And you should move away from version checking.
Many of us faces product requirements such as "support Windows Vista through Windows 8.1." Not supporting can mean any number of things, such as refusing to run, run with a warning message, or not submitting telemetry data to the backend. I don't know how to do that without version checking.
To Microsoft, "not supporting" means run at your own risk, e.g. if you run Windows XP or DOS now, Microsoft will not stand in your way, but it won't help you either. Your "not supporting" definition looks like support to me, you have to actually ensure it runs in an unusual way that denies service to the customer and the code must be future-proof. This is a support burden that Microsoft refused to take. So if you have to support this by yourself, you need to test the version detection code when each Windows version is released and keep your customer's installation up to date. You can't really prove your code is future-proof unless you got a time machine, but at least you can say it is current-proof (support Windows Vista through Windows 8.1, won't run on all public Windows 10 builds as of date mm/dd/yyyy).
Visual C++ MVP
- Edited by Sheng Jiang 蒋晟MVP Monday, February 02, 2015 10:25 PM
The Version Helpers are great and I do use them. They seem to validate my assumption that version numbers in a populated OSVERSIONEX structure will be going up with future version of Windows. In other words, ex ante, I may not be able to know if Windows 10 will be 6.4 or 10.0, but I can be reasonably sure that either is considered higher than 6.3, and thus determine that that OS version is later than 8.1.
The version number for Windows 10 is expected to be 10.0. It was 6.4 for the first Technical Preview.
GetVersion(Ex) is deprecated, and with Windows 8.1 and Windows 10 it will by default apply a 'version lie shim' unless you have the appropriate <compatibility> manifest section.
If you use VerifyVersionInfo, then you can use 6.4 >= and will detect both Windows 10 or later and the Windows 10 Technical Preview. This API behavior is not affected by the manifest section.
- Proposed as answer by Chuck Walbourn - MSFTMicrosoft employee Tuesday, February 03, 2015 12:58 AM
Chuck Walbourn - MSFT wrote:>>The version number for Windows 10 is expected to be 10.0. It was 6.4>for the first Technical Preview.>>GetVersion(Ex) is deprecated, and with Windows 8.1 and Windows 10 it>will by default apply a 'version lie shim' unless you have the>appropriate <compatibility> manifest section.I have said before and I will say again that this was an idiotic thing forMicrosoft to do.A perfectly reasonable use for GetVersionEx is to put up a string in an"about box" or a "send this to support" box saying what version of Windowsis actually in use, and you have now broken that for existing binaries thatwould otherwise still be working perfectly well 20 years later.GetVersionEx was itself a 1995 replacement for an earlier API. Thedocumentation for this new API stated the rules for its use. WhatMicrosoft has done here is to penalize permanently those developers whofollowed the rules, in order to pander to morons who can't read the doc. Itwas an extremely poor decision.--Tim Roberts, email@example.comProvidenza & Boekelheide, Inc.
Tim Roberts, VC&amp;#43;&amp;#43; MVP Providenza &amp; Boekelheide, Inc.
RtlGetVersion is the kernel-mode equivalent of GetVersionEx, and is not subject to the OSVersionLie shim.
You can continue to use GetVersionEx if desired, and apply a <compatibility> section to your EXE. This change is mostly just making explicit something that has already been true for over a decade: at some point, your application could well get a 'version lie' result from this API.
Marking this API deprecated is forcing developers to take a look at their use of it, consider if there are in fact better options (like VerifyVersionInfo/OSVersionHelpers or other mechanisms), and then if they continue to use it they do so with the full knowledge of the modified OS contract that applies to it.
The fact that the version number for the early technical preview was 6.4 and the current builds is 10.0 is a result of the alpha/beta process and is not really the issue at hand w.r.t. to GetVersionEx. In point of fact, the presence of the default OSVersionLie behavior for GetVersionEx actually allowed the OS major version to change without breaking applications.
Telemetry/diagnostic reporting has been a legitimate use of GetVersionEx for many years, but with the Windows 10 update model it's not likely to be all that relevant anyhow.
- Edited by Chuck Walbourn - MSFTMicrosoft employee Sunday, February 22, 2015 9:36 PM
Chuck Walbourn - MSFT wrote:>>Telemetry/diagnostic reporting has been a legitimate use of GetVersionEx>for many years, but with the Windows 10 update model it's not likely to>be all that relevant anyhow.How can you possibly say that? Again, my point here is NOT that you havemade NEW software any more difficult. My point is that you have BROKENsoftware that has been working for 20 years. It is a compatibilityfailure.--Tim Roberts, firstname.lastname@example.orgProvidenza & Boekelheide, Inc.
Tim Roberts, VC&amp;#43;&amp;#43; MVP Providenza &amp; Boekelheide, Inc.
I really dont think so. I did many test with VerifyVersionInfo with the win10 build 9926.
It failed to detect 10.0 or 6.4 without manifest.
and we checked this problem with MS team (PROGRAM MANAGER
OSG Ecosystem and Frameworks | ISV Readiness) and other MS Win10 testing/dev team member. What they replied is new VerifyVersionInfo needs manifest and some other Rtl API wont be 100% sure if it would be modified or not.
And MS team also confirmed that MSDN document needs some modification for VerifyVersionInfo.
this undocumented modification is truly annoyed for programmer especially those programmer coding win MS platform for more than 15 years.
Alas, the behavior changed recently. VVI now behaves exactly the same as GetVersionEx w.r.t. to the manifests in recent flights of Windows 10. This information is not yet reflected on MSDN. This means that using VersionHelpers.h works in most cases on Windows 10, but returns 'false' for IsWindows8Point1OrGreater() and IsWindows10OrGreater() unless you had the required manifest elements.
- Edited by Chuck Walbourn - MSFTMicrosoft employee Monday, March 30, 2015 2:56 AM
Especially the device driver system core stuff.
We even dont know the GUID of windows 10, win10.1. win11. How could we know it from now? Even MS wont know.
If you truly think this kind of OS version checking is useless.
Why MS has designed this all over system.
there are RtlGetVersion. GetVersionInfo, GetVersionInfoEx VerifyVersionInfo, so many versions, WHY?
Even kernel mode, there are functions to get OS version number.
Even old compiler + SDK can make most code working in newer OS. but have to do LoadLibrary etc work. but it is doable anyway.
But why Version check must be screwed that way. I dont get it.
How to make sure the API i am using now working with Windows 10 wont be screwed in Windows 10.1 or Windows 10.
The OS version checking is most efficent way, if it is win10.1 found and we are sure we only tested win10 and never win10.1. then we at least can tell user this wont work at win10.1 if something wrong happens there. Same API but Windows retruns false report. what the hell this is?
"Application was not tested on this OS and may behave unpredictable. Do you want to run it at you own risk?"
This is especially true for system software which has drivers etc
How can we do it with manifest? no way?
Long story short - you never can make code compatible with all future OS, period
No matter what MS says
This is utopia
It was always so
in history of Windows
New OS always breaks something
So version checking is needed at least to know that we are on well known and SUPPORTED OS.
MS manifests do not achieve this goal
in opposite - they are destructive and make user experience worse
This can be ok only for small Hello, world! apps
but not for real one especially with drivers
MS never has full backward compatibility
eg, it can be some small bug in specific OS version or service pack
and application will break
Users will mail our support and say we are assholes
But we just could not test this new OS
how can we make sure our code works on all new OS? no way
And if MS reports old OS version to us then we cannot even detect that crappy OS
"Developer can be sure only about OS he tested HIMSELF!!!"
- Edited by 20vtfan Monday, March 30, 2015 5:02 PM
It turns out the exact the same problems that lead to the appcompat team defaulting to shim behavior on GetVersionEx also affect VerifyVersionInfo because both APIs are routinely abused for component checks and other fragile behavior.
If you apply the <compatibility> manifest elements with a Windows 8.1 and Windows 10 GUID present, you will get 'true' behavior for VerifyVersionInfo and GetVersionEx, but you are still strongly encouraged to minimize any use of these APIs as much as possible.
A "you must be this high to ride this ride" style >= check with VerifyVersionInfo is still generally safe, and it's unlikely Windows desktop application are actually going to set a minimum bar of "Windows 8.1 or higher" or "Windows 10 or higher" for the foreseeable future--Windows 8 Store and universal Windows apps are not able to use either GetVersion(Ex) or VerifyVersionInfo. IsWindowsXPSP3OrGreater(), IsWindowsVistaSP2OrGreater(), IsWindows7OrGreater(), or IsWindows8OrGreater() works exactly as you'd expect even without the manifest.
So, again, the question is what are you actually trying to achieve by using these APIs? In most cases, there are more direct and robust ways to achieve the right test, and they don't involve either GetVersion(Ex) or VerifyVersionInfo.
Furthermore, with the Windows 10 servicing model, the OS version number itself is becoming less meaningful, and the existing set of Windows Vista, Windows 7, Windows 8, Windows 8.1, and Windows 10 GUIDs are likely to be exhaustive for some time.
I'm sorry I wasn't aware of the plans to add this behavior to VVI for Windows 10 earlier. This change is in the public Windows 10 flights for validation, but all the auxiliary changes such as MSDN, deprecation warnings in headers, updated appcompat guideance, etc. are still in development.
There is always cases where we can't avoid to check the version.
For example, I want to use the robocopy utility to synchronize data. Its options change on each new version of Windows. If I want to use the newer features while keeping a compatibility with Vista, I have no other way but to check the OS version before building my command line.
I could check the return value of robocopy but this not documented ("Any value greater than 8 indicates that there was at least one failure during the copy operation."). Therefore, I cannot be sure that this is because of an unrecognized switch.
Another example. How are we supposed to check the availability of the SERVICE_ACCEPT_PRESHUTDOWN notification? On XP, the behavior is unpredictable (and seemingly not desirable at all). So, only one solution: check the OS version.
There are always features for which the availability cannot be checked, or in a very bad way. Therefore, we need to check the OS version. You cannot avoid that.
We will always find a way to check the OS version, because a newer OS always presents differences with its previous version.
You can only make things more complicated for developers.
will you are relying on undocumented behavior instead of a code contract from Microsoft, is it a surprise to you that it breaks when a new Windows version or service pack is released?
The earlier you move away from robocopy the better. It is made for a specific problem, and that problem isn't a sync platform for third party software. If you are looking at a Microsoft solution, there's a Microsoft Sync Framework. There are plenty others you can find under https://en.wikipedia.org/wiki/Comparison_of_file_synchronization_software#Open_source.
Visual C++ MVP
- Edited by Sheng Jiang 蒋晟MVP Tuesday, May 12, 2015 5:16 PM
Shelling to robocopy is indeed likely to be platform-specific, and perhaps something you should be handling in another way.
As for specifically implementing a workaround dealing with issues on a particular version, then you can use VerifyVersionInfo == tests for that case. Even if you did not add the <compatibility> section to your app--which we've already mentioned in this thread a number of times--you will still get 'correct' answers from VVI for questions like "Is this Windows XP?" "Is this Windows Vista?" "Is this Windows 7?".
I just checked with today's release of Windows 10 and VerifyVersionInfo == test returns TRUE for 6.2 (Windows 8) without the <compatibility> section in my app.
I had expected it to return TRUE for either 6.4 or 10.0 for Windows 10
- Edited by Gudnar Friday, July 31, 2015 4:47 AM more info
As noted in the thread history, VerifyVersionInfo in Windows 10 behaves exactly like GetVersionEx did in Windows 8.1: Without the <compatibility> section it behaves as if the "true" version number is 6.2 (Windows 8.0).
The recommended solution is: don't do version checks. That said, all of the VersionHelpers.h checks will work as expected on all versions of Windows including Windows 10 except for IsWindows8_1OrGreater and IsWindows10OrGreater.
So the question is: Why are you doing a version check in the first place? There is most likely a better way to get the information you really need directly.
We are in this situation. There are a few reasons why we need to know the Operating System version
1. We need to know the Operating System version for licensing purposes, and the licensing program needs to be able to run on and handle future Operating Systems without a recompile.
2. We need to be able to detect the Operating System version as we over time no longer support our applications on older Operating Systems.
- Edited by Tor Cro Friday, July 31, 2015 7:21 AM
1. Without knowing more about your 'licensing program' I can't really make any suggestions.
2. Unless you are specifically trying to prevent running on Windows 8.1 or Windows 10, VerifyVersionInfo / VersionHelpers.h works "as is" in Windows desktop apps even without the manifest to handle these 'you must be this high to ride this ride' styles of checks. If it does require Windows 8.1 or Windows 10 as the 'oldest supported version', then adding the embedded manifest with the compatibility section resolves this concern as well.
- Edited by Chuck Walbourn - MSFTMicrosoft employee Tuesday, September 22, 2015 9:38 PM
Windows 10 supports USB CDC out of the box. So there is no need for us to install our product's driver on these machines. But someone very clever decided not to make msiexec.exe Windows 10 compatible, it is 8.1 only. So we're indirectly affected by this GetVersionEx misbehavior, the VersionNT/64 property gets wrongly set to 603 and can't be used as condition. Thank you very much, Microsoft. It could be so easy...