Получение основных, второстепенных и сборочных версий ОС для Windows 8.1 и выше в Delphi 2007

Я видел в нескольких вопросах / ответах о том, как определить версию ОС Win 8.1 и 10.0 с помощью VerifyVersionInfo (поскольку GetVersionEx больше не работает без проявления), но это позволяет мне только проверить, является ли ОС версией, которую вы передаете функция. Это не возвращает эту информацию мне. Например, в случае GetVersionEx он сообщает мне основные, вспомогательные и сборочные версии, но в случае VerifyVersionInfo мне необходимо задать вопрос: "Версия ОС 6.3 или выше?". или "Версия ОС 10.0 или выше?" поскольку GetVersionEx теперь возвращает 6,2 для версии ОС, даже если это на самом деле 6,3 или 10,0.

Это хорошо, потому что я могу легко добавить эту проверку в свой код, но теперь у меня нет возможности получить версию сборки, так как VerifyVersionInfo не сообщает мне об этом. Можно ли получить версию сборки каким-либо другим способом?

Вот что я делаю сейчас, чтобы определить, является ли ОС 8.1 или 10.0:

function IsWindowsVersionOrGreater(wMajorVersion, wMinorVersion, wServicePackMajor: Word): Boolean;
var
  osvi: OSVersionInfoEX;
  dwlConditionMask: Int64;
begin
  FillChar(osvi, sizeof(osvi), 0);
  osvi.dwOSVersionInfoSize := SizeOf(osvi);
  osvi.dwMajorVersion := wMajorVersion;
  osvi.dwMinorVersion := wMinorVersion;
  osvi.wServicePackMajor := wServicePackMajor;
  dwlConditionMask := VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
  dwlConditionMask := VerSetConditionMask(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
  dwlConditionMask := VerSetConditionMask(dwlConditionMask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
  Result := VerifyVersionInfo(osvi, VER_MAJORVERSION or VER_MINORVERSION or VER_SERVICEPACKMAJOR, dwlConditionMask);
end;

function IsWindows8Point1OrGreater: Boolean;
begin
  Result := IsWindowsVersionOrGreater(HIBYTE(WIN32_WINNT_WINBLUE), LOBYTE(WIN32_WINNT_WINBLUE), 0);
end;

function IsWindows10OrGreater: Boolean;
begin
  Result := IsWindowsVersionOrGreater(HIBYTE(WIN32_WINNT_WIN10), LOBYTE(WIN32_WINNT_WIN10), 0);
end;

function GetWinVersion: string;
var
  osVerInfo: TOSVersionInfo;
  majorVersion, minorVersion: Integer;
begin
  Result := '?.?';
  osVerInfo.dwOSVersionInfoSize := SizeOf(TOSVersionInfo) ;
  if GetVersionEx(osVerInfo) then
  begin
    minorVersion := osVerInfo.dwMinorVersion;
    majorVersion := osVerInfo.dwMajorVersion;

    if (majorVersion = 6) and (minorVersion = 2) then
    begin
      if IsWindows10OrGreater() then              // 8.1+ does not report correct version.
        Result := '10.0'                          // NOTE: NO BUILD NUMBER
      else if IsWindows8Point1OrGreater() then
        Result := '6.3'
      else                                        // This 6.2 is actually Win 8
        result:=inttostr(majorVersion)+'.'+inttostr(minorVersion)+'.'+inttostr(osVerInfo.dwBuildNumber);
    end
    else
      result:=inttostr(majorVersion)+'.'+inttostr(minorVersion)+'.'+inttostr(osVerInfo.dwBuildNumber);
    end;
 end;

РЕДАКТИРОВАТЬ: Как предложил Дэвид, решение было использовать WMI. Это работает с Win 8.1 и Win 10 и не требует наличия обновленного манифеста с каждой новой версией Windows.

function  GetWinVersion8AndUp(): String;
const
  WbemUser            ='';
  WbemPassword        ='';
  WbemComputer        ='localhost';
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;
begin;
  Result := '';

  try
  try
    FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
    FWMIService   := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
    FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_OperatingSystem','WQL',wbemFlagForwardOnly);
    oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
    while oEnum.Next(1, FWbemObject, iValue) = 0 do
    begin
      Result := Format('%s',[String(FWbemObject.Version)]);

      FWbemObject:=Unassigned;
    end;
  except
  end;
  finally
  end;
end;

0 ответов

Другие вопросы по тегам