【问题标题】:How I can detect if my application is running under compatibility mode? [duplicate]如何检测我的应用程序是否在兼容模式下运行? [复制]
【发布时间】:2012-05-31 11:02:08
【问题描述】:

可能重复:
How to detect true Windows version

我有一个应用程序使用第三方库(dll - 无源代码)来保护(加密)一些客户数据,这个 dll 必须使用不同的参数初始化,具体取决于当前的 Windows 版本。如果我的应用在 Windows 7 下以 XP 兼容模式执行,则 dll 加密方法失败。所以我需要一种方法来检测我的应用程序何时在兼容模式下运行以防止此问题。所以How I can detect if my application is running under compatibility mode?

【问题讨论】:

  • 检查加密是否失败似乎是一个显而易见的解决方案。
  • 我认为这个问题很有价值,并且足够不同,可以将其分开。不投票结束。

标签: windows delphi


【解决方案1】:

您可以将GetVersionEx 函数返回的值与Win32_OperatingSystem WMI 类的 Version 属性进行比较。

试试这个示例

{$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.

【讨论】:

  • 还有其他几种方法可以检测真正的操作系统版本,而不仅仅是 WMI。 RtlGetVersion()NetServerGetInfo()NetWkstGetInfo() 也可以。此外,影响GetVersionEx()的不仅仅是兼容模式,在Windows 8.1+ Manifestation 中也会影响它,因此仅检查版本号并不表示使用了兼容模式本身,尽管它确实表明存在某种虚拟化效果一般。
猜你喜欢
  • 1970-01-01
  • 2015-12-16
  • 1970-01-01
  • 2015-11-26
  • 2016-12-29
  • 1970-01-01
  • 1970-01-01
  • 2012-09-08
  • 1970-01-01
相关资源
最近更新 更多