2

Possible Duplicate:
How to detect true Windows version

I have an application which uses a third-party library(dll - no source code) which protect (encrypt) some customer data, this dll must be initializated using different params depending of the current Windows Version. If my app is executed in XP compatibility mode under Windows 7, the dll encrypt method fails. So i need a way to detect when My App is running under compatibility mode to prevent this issue. So How I can detect if my application is running under compatibility mode?

Community
  • 1
  • 1
Salvador
  • 16,132
  • 33
  • 143
  • 245

1 Answers1

7

You can compare the value returned by the GetVersionEx function against the Version property of the Win32_OperatingSystem WMI class.

Try this sample

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Windows,
  SysUtils,
  ActiveX,
  ComObj,
  Variants;

function WMI_OSVersion:string;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  rgvar         : OLEVariant;
  LEnum         : IEnumVARIANT;
  pceltFetched  : LongWord;
begin
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
  FWbemObjectSet:= FWMIService.ExecQuery('SELECT Version FROM Win32_OperatingSystem','WQL', $00000020);
  LEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  if LEnum.Next(1, rgvar, pceltFetched) = S_OK  then
   Result:=String(rgvar.Version);
end;

function WinApi_OsVersion:string;
var
  lpVersionInformation: TOSVersionInfo;
begin
  ZeroMemory(@lpVersionInformation, SizeOf(lpVersionInformation));
  lpVersionInformation.dwOSVersionInfoSize:=SizeOf(lpVersionInformation);
  GetVersionEx(lpVersionInformation);
  Result:=Format('%d.%d.%d',[lpVersionInformation.dwMajorVersion, lpVersionInformation.dwMinorVersion, lpVersionInformation.dwBuildNumber]);
end;

function RunningCompatibilityMode : Boolean;
begin
   Result:=WMI_OSVersion<>WinApi_OsVersion;
end;

begin
 try
    CoInitialize(nil);
    try
      Writeln('Running in Compatibility Mode - '+ BoolToStr(RunningCompatibilityMode, True));
    finally
      CoUninitialize;
    end;
 except
    on E:EOleException do
        Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;
end.
RRUZ
  • 134,889
  • 20
  • 356
  • 483
  • There are several other ways to detect the true OS version, not just WMI. `RtlGetVersion()`, `NetServerGetInfo()`, `NetWkstGetInfo()` also work. Also, It is not just Compatibility Mode that affects `GetVersionEx()`, in Windows 8.1+ Manifestation also affects it as well, so just checking version numbers does not indicate the use of Compatibility Mode itself, though it does suggest some kind of virtualization is in effect in general. – Remy Lebeau Feb 05 '16 at 21:59