Thursday, July 19, 2007

Checking the Windows Version

Sometimes there is a need to detect which operating system the application is running on. In Menus.pas you can find the following code but a bit more spread out so I've consolidated it here into a nice easy to read chunk:

Note: The checks are for that version or later.

var
Win98Plus, Win2K, WinXP, WinVista, Win7: Boolean;
begin
Win98Plus := (Win32MajorVersion > 4) or
((Win32MajorVersion = 4) and (Win32MinorVersion > 0));
Win2K := (Win32MajorVersion > 4) and
(Win32Platform = VER_PLATFORM_WIN32_NT);
WinXP := CheckWin32Version(5, 1);
WinVista := CheckWin32Version(6, 0);
Win7 := CheckWin32Version(6, 1)
end;

5 comments:

stanleyxu said...

You'd better addd suffix "OrLater" to each variable.

Chris B. said...

Stan,

Hey, this isn't my code, you can find it in the Menus.pas ;) What about AtLeastWin98Plus instead of OrLater?

Joe White said...

Wouldn't it be better if the RTL defined a TWindowsVersion record, complete with several static methods (TWindowsVersion.Windows98, TWindowsVersion.Windows2000Server, etc.) and operator overloading, so you can say "if WindowsVersion >= TWindowsVersion.Windows95OSR2"?

Loïs Bégué said...

Maybe I drank to much beer yesterday evening ;) but my crystal ball is showing me the following code:

begin

WinVista := CheckWin32Version(6, 0);

WinXP := Not WinVista and CheckWin32Version(5, 1);

Win2K := Not (WinXP or WinVista) and (Win32MajorVersion > 4) and (Win32Platform = VER_PLATFORM_WIN32_NT);

Win98Plus := Not (Win2K or WinXP or WinVista) and (Win32MajorVersion > 4) or ((Win32MajorVersion = 4) and (Win32MinorVersion > 0));

End;

stanleyxu said...

I have extended CheckWin32Version, which can detect service package as well.


// Compares a set of operating system version requirements to the corresponding values for the
// currently running version of the system.

type
OSVERSIONINFOEXA = packed record
dwOSVersionInfoSize: DWORD;
dwMajorVersion: DWORD;
dwMinorVersion: DWORD;
dwBuildNumber: DWORD;
dwPlatformId: DWORD;
szCSDVersion: array[0..127] of Char;
wServicePackMajor: Word;
wServicePackMinor: Word;
wSuiteMask: Word;
wProductType: Byte;
wReserved: Byte;
end;
TOSVersionInfoExA = OSVERSIONINFOEXA;
POSVersionInfoExA = ^TOSVersionInfoExA;

const
VER_GREATER_EQUAL = 3;
VER_MINORVERSION = $0000001;
VER_MAJORVERSION = $0000002;
VER_SERVICEPACKMINOR = $0000010;
VER_SERVICEPACKMAJOR = $0000020;

type
// Win2k/XP/Vista or later
TVerSetConditionMask = function(ConditionMask: LONGLONG; TypeMask: DWORD; Condition: Byte): LONGLONG; stdcall;
// Win2k/XP/Vista or later
TVerifyVersionInfoA = function(var VersionInformation: OSVERSIONINFOEXA; dwTypeMask: DWORD; dwlConditionMask: LONGLONG): BOOL; stdcall;

function Win32PlatformGreaterOrEqual(AMajorVersion, AMinorVersion: DWORD; AServicePackMajor, AServicePackMinor: Word): Boolean;
var
hLib: THandle;
PtrP: TFarProc;
VerifyVersionInfoA: TVerifyVersionInfoA;
VerSetConditionMask: TVerSetConditionMask;
OSVI: TOSVersionInfoExA;
dwlConditionMask: LONGLONG;
op: Integer;
begin
Result := False;

// To make sure that your OS has these two APIs.
hLib := LoadLibrary('kernel32.dll');
if hLib = 0 then
Exit;
PtrP := GetProcAddress(hLib, 'VerifyVersionInfoA');
if PtrP = nil then
Exit;
VerifyVersionInfoA := TVerifyVersionInfoA(PtrP);
PtrP := GetProcAddress(hLib, 'VerSetConditionMask');
if PtrP = nil then
Exit;

// Initialize the condition mask.
VerSetConditionMask := TVerSetConditionMask(PtrP);
dwlConditionMask := 0;
op := VER_GREATER_EQUAL;
dwlConditionMask := VerSetConditionMask(dwlConditionMask, VER_MAJORVERSION, op);
dwlConditionMask := VerSetConditionMask(dwlConditionMask, VER_MINORVERSION, op);
dwlConditionMask := VerSetConditionMask(dwlConditionMask, VER_SERVICEPACKMAJOR, op);
dwlConditionMask := VerSetConditionMask(dwlConditionMask, VER_SERVICEPACKMINOR, op);

// Initialize the OSVERSIONINFOEX structure.
FillChar(OSVI, SizeOf(OSVI), #0);
OSVI.dwOSVersionInfoSize := SizeOf(OSVI);
OSVI.dwMajorVersion := AMajorVersion;
OSVI.dwMinorVersion := AMinorVersion;
OSVI.wServicePackMajor := AServicePackMajor;
OSVI.wServicePackMinor := AServicePackMinor;

Result := VerifyVersionInfoA(
OSVI,
VER_MAJORVERSION or VER_MINORVERSION or VER_SERVICEPACKMAJOR or VER_SERVICEPACKMINOR,
dwlConditionMask
);
end;

Post a Comment