Windows 10 GetVersionEx RRS feed

  • Question

  • Hi All,

    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.

    Monday, February 2, 2015 6:35 PM

All replies

  • 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

    Monday, February 2, 2015 7:03 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.

    Monday, February 2, 2015 8:25 PM
  • 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

    Monday, February 2, 2015 10:24 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.

    Monday, February 2, 2015 11:12 PM
  • 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.


    Tuesday, February 3, 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 for
    Microsoft 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 Windows
    is actually in use, and you have now broken that for existing binaries that
    would otherwise still be working perfectly well 20 years later.
    GetVersionEx was itself a 1995 replacement for an earlier API.  The
    documentation for this new API stated the rules for its use.  What
    Microsoft has done here is to penalize permanently those developers who
    followed the rules, in order to pander to morons who can't read the doc. It
    was an extremely poor decision.
    Tim Roberts, timr@probo.com
    Providenza & Boekelheide, Inc.

    Tim Roberts, VC&amp;amp;#43;&amp;amp;#43; MVP Providenza &amp;amp; Boekelheide, Inc.
    Sunday, February 8, 2015 7:54 PM
  • Agreed about MS's mistake with GetVersionEx.  I've had to switch everything from using that to RtlGetVersion which works correctly (for some reason), but the whole thing is a big nuisance.
    Sunday, February 22, 2015 6:04 PM
  • 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.

    Sunday, February 22, 2015 8:55 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 have
    made NEW software any more difficult.  My point is that you have BROKEN
    software that has been working for 20 years.  It is a compatibility
    Tim Roberts, timr@probo.com
    Providenza & Boekelheide, Inc.

    Tim Roberts, VC&amp;amp;#43;&amp;amp;#43; MVP Providenza &amp;amp; Boekelheide, Inc.
    Monday, March 9, 2015 5:27 AM
  • @Chuck



    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.


    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.


    Sunday, March 29, 2015 6:59 PM
  • 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.

    Monday, March 30, 2015 2:54 AM

  • Serious?

    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
    Monday, March 30, 2015 5:01 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.

    Monday, March 30, 2015 6:20 PM
  • 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.

    Tuesday, May 12, 2015 3:45 PM
  • 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

    Tuesday, May 12, 2015 5:02 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?".

    Tuesday, May 12, 2015 6:04 PM
  • 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

    Now what?

    • Edited by Gudnar Friday, July 31, 2015 4:47 AM more info
    Friday, July 31, 2015 3:54 AM
  • 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.

    Friday, July 31, 2015 6:36 AM
  • 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
    Friday, July 31, 2015 7:20 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.

    Tuesday, September 22, 2015 9:37 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...

    Wednesday, September 23, 2015 11:44 AM
  • Chuck,

    how can I get **real** operating system version for diagnostic purposes?

    Which API function should I use? GetVersionEx was crippled, on Windows 10, 8.1 it returns crappy nonsense.

    It's not likely kind of assumptions are wrong assumptions — „640K ought to be enough for anybody...“.

    Wednesday, October 18, 2017 3:58 PM
  • if you want the APIs to report Windows 10, write that your app is Windows 10-aware in your application manifest. The version lie shim is for making sure outdated apps still work. When you can still deliver updates the burn of compatibility is on you.

    Visual C++ MVP

    Wednesday, October 18, 2017 5:43 PM
  • Manifest your file to be compatible with Windows 10 and then call GetVersionEx.

    The documentation for this function tells you how to do this, and it doesn't take much work. You just add a file to your project and put it as an input for the manifest tool.

    #include <Windows.h>
    #include <cstdio>
    int wmain()
    	ovx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
    	GetVersionExW(reinterpret_cast<OSVERSIONINFOW *>(&ovx));
    	wprintf(L"Windows Version %d.%d.%d", ovx.dwMajorVersion, ovx.dwMinorVersion, ovx.dwBuildNumber);
    	return 0;

    Gave me:

    Windows Version 10.0.16299

    With only that minor modification.

    Add a file with a .manifest extension in your project, you can create it using the text file template and just change the name. Then add:

    <?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">
        <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> 
                <!-- Windows 10 --> 
                <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
                <!-- Windows 8.1 -->
                <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
                <!-- Windows Vista -->
                <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> 
                <!-- Windows 7 -->
                <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
                <!-- Windows 8 -->
                <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>

    to the file. This is the compatibility information, if you wanted to add other settings, like the default high DPI settings then you can put it in this file. If you already have a file for that, you can put this into there.

    Go to the project settings, and in the manifest tool settings, add the file name you just added to the Additional Manifest Files of the manifest tool. It should look like:

    I obviously named the file app.manifest. Then just build your application. This manifest will be merged with the default application manifest and your application will be marked as compatible with all versions of Windows up to 10. GetVersionEx will then also report the version as 10.

    You can verify that this has worked by disabling the embed manifest option. Go to where the application you just built was built, and in the same directory there should be a file name <application name>.exe.manifest. If you look in that file you should see the compatibility stuff there. if you undo adding the compatibility stuff to the manifest then you will notice that it will vanish. Simple.

    This is a signature. Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Wednesday, October 18, 2017 6:10 PM
  • was für eine Sch.... von MS
    Den Mist muss man nicht verstehen
    • Edited by asrx Friday, July 31, 2020 1:09 PM
    Friday, July 31, 2020 1:08 PM