Version Checking (Just Don’t Do It)

Version Checking (Just Don’t Do It)

  • Comments 4
  • Likes

Version checking is probably one of the most common Application Compatibility issues that both developers and users are facing. This is another post in a series of posts about Getting Ready for Windows 7.

As said, this is probably the most common application compatibility issue that users as well as developers face is when an application fails upon checking the operating system version. A lot can go wrong when version checking is misused. A user might experience a “silent fail” where the application simply fails to load and nothing happens. Or, a user might see a dialog box indicating something to the effect of “you must be running Microsoft Windows XP or later” when in fact, the computer is running Windows 7. Many other consequences to poor version checking can inconvenience users as well.

Applications fail due to version checking for two main reasons:

  • A flaw (bug) in the version checking code, which fails if the minor version is decreased, even if the major version is increased, for example, changing versions from 5.1(Windows XP) to 6.0 (Windows Vista), or if the expected service pack (SP) is not installed, even if you're running a newer operating system (for example, changing versions from Windows XP SP 2 to Windows Vista SP 1). We recommend that you check functionality rather then checking version, as you can read in this post.
  • An intentional blocking that prevents the application from running on operating system versions not tested by its developers. We recommend that you do not block applications from running on future operating systems.

When an application runs on an "incompatible" (due to poor version checking) version of Windows, it will generally display an error message, but it may also exit silently or behave erratically. Often, if we work around the version checking, the application will run well. End-users and IT professionals may apply a fix to let the application think it is running on an older version of Windows.

Working Around The Problem (not really solving the bug)

Compatibility mode: Designed for end users (not for developers to not fix their bugs), compatibility mode is an easy way to work around compatibility issues. When enabled, it applies a set of compatibility fixes that provide a runtime environment more compatible with applications written for older versions of Windows. One of those fixes is the "version lie," which makes the version query functions return the operating system version the user chose in the Compatibility tab of the Properties dialog box instead of the actual Windows version.

To enable compatibility mode:

  • Right-click the executable or shortcut to the executable.
  • Click Properties.
  • Click the Compatibility tab.
  • Enable Run this program in compatibility mode for: and select the operating system version you think the application should be able to run on.
    Some applications consist of several executables. You may need to apply this fix to each one.


  • Click OK to close the dialog box.
  • Run the application.

Checking for Features Rather Than Version

As mentioned previously, checking the operating system version is not the best way to confirm that a specific operating system feature is available. This is because the operating system may have had new features added in a redistributable DLL. Rather than using GetVersionEx to determine the operating system platform or version number, it is more effective to test for the presence of the feature itself. For example, we plan to make the Direct2D and DirectWrite APIs and the Ribbon API available in Windows Vista, so there is no need to block your application from using these APIs when running on Windows Vista. You just need to check if these features are available on the Operation System that you are running. If possible, your application should still run if the feature is unavailable, though with reduced functionality or performance.

You can use one of the following techniques to find out if a specific features is available on the given OS.

For Win32 developers:

  • Use LoadLibrary() to load a library which is not yet loaded into your application. If you are interested in a new function of a DLL which is already loaded (for example, kernel32.dll), then call GetModuleHandle() to obtain the module handle. If either of these functions return NULL, then this indicates an error.
  • Use GetProcAddress() to obtain a function pointer. If GetProcAddress() returns NULL, then the function may not exist. Cast the pointer to a function pointer of an appropriate prototype. Some functions, although they exist may actually be stubs that return a "not implemented" error. Be such to check for such errors.

Windows 7 introduces a new timer API - SetWaitableTimerEXProc, which adds one more input variable to the regular SetWaitableTimerProc. The TolerableDelay lets you specific a time tolerance window in which the timer can expire. This is a new in Windows 7, that we will use to demonstrate how to check for feature.

      // define function pointer type
    typedef BOOL (WINAPI *SetWaitableTimerExProc)(
      __in  HANDLE hTimer,
      __in  const LARGE_INTEGER *lpDueTime,
      __in  LONG lPeriod,
      __in  PTIMERAPCROUTINE pfnCompletionRoutine,
      __in  LPVOID lpArgToCompletionRoutine,
      __in  PREASON_CONTEXT WakeContext,
      __in  ULONG TolerableDelay

    LARGE_INTEGER liDueTime;
    liDueTime.QuadPart = 0;
    nt period = 1000;
    unsigned int tolerance = 1000;
    HANDLE hTimer = // Get timer handle

    REASON_CONTEXT reasonContext = {0};
    reasonContext.Version = 0;
    reasonContext.Reason.SimpleReasonString = L"MyTimer";

    // Get module handle to a module which is already loaded
    HMODULE hKernel32Module = GetModuleHandle(_T("kernel32.dll"));
    if (hKernel32Module == NULL)
        return FALSE;

    // Get Address of function
    SetWaitableTimerExProc pFnSetWaitableTimerEx =
    (SetWaitableTimerExProc) ::GetProcAddress(hKernel32Module,     

    // Check if the function exists    
    if (pFnSetWaitableTimerEx == NULL)
        return FALSE;

    // Call function
    if (!pFnSetWaitableTimerEx(hTimer, &liDueTime, period, NULL, NULL,
            &reasonContext, tolerance)
    { // handle error }

Alternatively, you may use DLL delayed loading and call functions in a __try...__except block. (For more information, see Linker Support for Delay-Loaded DLLs.)

For COM APIs, handle errors returned by CoCreateInstance and QueryInterface.NET framework applications that call Win32 APIs via P/Invoke should handle EntryPointNotFoundException and DllNotFoundException exceptions.


If You Must Check OS Version Number

Identifying the current operating system is not the best way to determine whether a particular operating system feature is present. However, if you can’t design your application to check for specific feature availability and the only way to ensure compatibility is through version checking, then please consider the following.

For native applications, you will need to ensure your application's logic will work with newer versions of Windows. Please DO NOT BLOCK on version change! The following is a Win32 code example that uses GetVersionEx. If the major version is greater than 5 (Windows Vista, Windows® Server 2008 R2 and Windows 7), the check passes. If it equals 5, then the minor version should be 1 or greater (Windows XP or Windows Server 2003).

#include <windows.h>
#include <stdio.h>

void main()
    BOOL bIsWindowsXPorLater;

    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);


    bIsWindowsXPorLater = 
 ( (osvi.dwMajorVersion > 5) ||
       ( (osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion >= 1) ));

  printf("The system meets the requirements.\n");
    else printf("The system does not meet the requirements.\n");

However there is a better way to verify the minimum OS version required using VerifiyVersionInfo(). This function compares a set of operating system version requirements to the corresponding values for the currently running version of the system. The following code example uses VerifyVersionInfo to check the operating system version against minimal requirements (Windows XP SP2):

#include <windows.h>
BOOL Is_WinXP_SP2_or_Later () 
   DWORDLONG dwlConditionMask = 0;

   // Initialize the OSVERSIONINFOEX structure.

   ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
   osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
   osvi.dwMajorVersion = 5;
   osvi.dwMinorVersion = 1;
   osvi.wServicePackMajor = 2;
   osvi.wServicePackMinor = 0;

   // Initialize the condition mask.


   // Perform the test.

   return VerifyVersionInfo(

In this code you can see how we use the VerifyVersion with a set of conditions to return TRUE incase we run on any OS grater than Windows XP Service Pack 2.


For .NET Framework developers, use the ==, !=, <=, <, >, >= operators of the Version object returned by Environment.OSVersion.Version:

// This code checks if the OS is at least Windows XP
  if (Environment.OSVersion.Version < new Version(5, 1))
        MessageBox.Show("Windows XP or later required.",
         "Incompatible Operating System", MessageBoxButtons.OK,

It is highly recommended that you don’t check for version at all and try looking to work with features. It will prove valuable for the future…

Just incase you want to read more, here are some useful links

You can also download a HOL and code sample for this topic.

You must be logged in to comment. Sign in or Join Now
  • adderek
    2 Posts

    Great article!

    One more thing you could think about is the application initialization. When an application is initialized then some code is executed. That might be several megabytes of code. What does it do after the initialization? It is usually not used ever again and the memory is still occupied. Desktop Windows does a good job with virtual memory (dumping that unused area to swap if needed) but mobile windows cannot do that (no swap).

    I think that Microsoft should create a framework to put initialization code outside the main application (ex. into external .dll and keeping only minimal loader in the .exe).

  • To newscientist2000

    If you fail your application due to version checking, you are damaging your end users experience. And this is exactly what this post is about. Your app should NOT fail and stop due to version checking…

  • I dont mind version checking, but I hate it when it stops you installing certain software on a future or prior version of Windows.  A warning to the end user should be given..i.e. this software was not designed to run on this version of windows, but ultimately the end user should decide if the risk is worth it.

    Compatibility mode has made a lot of these issues go away, and is a great feature.

  • anonymuos
    87 Posts

    So does the software "Designed for Windows 7" logo requirement ban apps that still do version checking and fail?


    -- Yes