Windows 7 Forums
Welcome to Windows 7 Forums. Our forum is dedicated to helping you find support and solutions for any problems regarding your Windows 7 PC be it Dell, HP, Acer, Asus or a custom build. We also provide an extensive Windows 7 tutorial section that covers a wide range of tips and tricks.



Windows 7: Version Checking (Just Donít Do It)

05 Aug 2009   #1

 
Version Checking (Just Donít Do It)

Quote:
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.Flags = POWER_REQUEST_CONTEXT_SIMPLE_STRING; 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, "SetWaitableTimerEx"); // 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 #include void main(){ OSVERSIONINFO osvi; BOOL bIsWindowsXPorLater; ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osvi); bIsWindowsXPorLater = ( (osvi.dwMajorVersion > 5) || ( (osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion >= 1) )); if(bIsWindowsXPorLater) 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 BOOL Is_WinXP_SP2_or_Later () { OSVERSIONINFOEX osvi; DWORDLONG dwlConditionMask = 0; int op=VER_GREATER_EQUAL; // 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. VER_SET_CONDITION( dwlConditionMask, VER_MAJORVERSION, op ); VER_SET_CONDITION( dwlConditionMask, VER_MINORVERSION, op ); VER_SET_CONDITION( dwlConditionMask, VER_SERVICEPACKMAJOR, op ); VER_SET_CONDITION( dwlConditionMask, VER_SERVICEPACKMINOR, op ); // Perform the test. return VerifyVersionInfo( &osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, dwlConditionMask);}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, MessageBoxIcon.Error); return; }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.


More...

My System SpecsSystem Spec
Reply

 Version Checking (Just Donít Do It)





Thread Tools




Our Sites

Site Links

About Us

Find Us

Windows 7 Forums is an independent web site and has not been authorized, sponsored, or otherwise approved by Microsoft Corporation. "Windows 7" and related materials are trademarks of Microsoft Corp.

© Designer Media Ltd

All times are GMT -5. The time now is 11:33 PM.
Twitter Facebook Google+



Windows 7 Forums

Seven Forums Android App Seven Forums IOS App
  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33