When a new OS is released, a high percentage of applications don’t install or don’t run because they check for a specific OS version.  The application or installer checks for a specific version number and exits if it isn’t what is expected. I’ve heard claims of up to 50% of incompatibility issues are due to a simple version checks.  So many applications check version that this influences how Microsoft increments version number.

Windows 7 = Windows 6.1

It’s true. If you look at the version number of Windows 7, it’s version 6.1.

C:\>ver

Microsoft Windows [Version 6.1.7600]

This was done for application compatibility. Most of the time, developers only check the major version. So, if Microsoft knows that application compatibility is very good between releases, only the minor version number is incremented. This trick was also done from Windows 2000 (5.0) to Windows XP (5.1).

Windows Knows How to Lie

Let’s say you only want your application to install on XP. Your installer checks the OS version and exits if it’s not equal to 5.1.  There’s a compatibility feature that has been in Windows since Windows 2000 called “shims”. Shims “trick” API calls by acting like a legacy OS. The “version lie” shim returns whatever OS version you want. Therefore, the installer can be tricked and the application can be installed regardless of the version check.  The “version lie” shim can be implemented several different ways -- by the user via the Compatibility tab in properties, the built-in “shim database”, by enterprise administrators via the ACT Toolkit, and by the Program Compatibility Assistant.

Don’t Check Version

The best option for checking version is to not do it. Sometimes you may feel that you need to check version (especially if your boss tells you).  Checking version and blocking the installation or exiting won’t stop the user if they are determined.  In fact, if you just exit, the user has no idea what has gone wrong.

The following table outlines why you may be version checking and suggestions to avoid problems:

Reason for Checking Version Suggestion
  • Protecting from the unknown. Concerned about the application failing on a future OS.
  • Need to control supported version. Don’t want the application to run on a non-supported OS.
  • Licensing
Check for version but don’t exit. Display a message to the user that this application was designed for a specific OS version and may not work or isn’t supported, etc. Point them to your website to look for a possible updated version.
  • Check version to enable certain functionality
  • Check version to load certain libraries or call different API’s
Don’t check version. Attempt to load library or call API and check for failure.  If failure, fall back to previous OS library or API.

For Example:

HMODULE hMod;

hMod = LoadLibrary(L"Apphelp.dll");

if (hMod) return hMod;

hMod = LoadLibrary(L"sdbapiu.dll");

if (hMod) return hMod;

hMod = LoadLibrary(L"sdbapi.dll");

if (hMod) return hMod;


 

 

Version Checks and OS Upgrades

One of the unusual side affects of version checking deals with upgrade scenarios. Here’s where version checking can get you into trouble.

  1. The application installs and runs just fine on an OS (e.g. 6.0).
  2. The OS is upgraded (e.g. 6.1).
  3. The application has a version check to exit if the OS is not equal to 6.0. Therefore, the application now exits on the newly upgraded OS.
  4. The installer has a version check to exit if the OS is not equal to 6.0.  The user tries to uninstall the application. The uninstaller exits because the OS is 6.1 and the user cannot uninstall the application.

Uh oh…

If You Must… The Most Correct Way to Check Version

If you decide to check version. Make sure you think through changes in major and minor version numbers. If you check for Windows 7, check for Windows 7 and greater so you don’t break when then next OS is released. 

Here’s some sample code that checks for OS versions:

if (dwMajorVersion >= 6 && dwMinorVersion >= 0)
    printf("MajorVersion>=6 && MinorVersion>=0. I'm Vista or greater\n");
else if (dwMajorVersion==5 && dwMinorVersion>=1)
    printf("MajorVersion==5 && MinorVersion>=1. I'm XP\n");
else if (dwMajorVersion==5 && dwMinorVersion==0)
    printf("MajorVersion==5 && MinorVersion==0. I'm Win 2000\n");
else
    printf("MajorVersion<5. I'm older than Win 2000\n");