Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Как определить версию Windows 11 в Delphi и Pascal, если RtlGetNtVersionNumbers возвращает Windows 10

Delphi , ОС и Железо , Windows

 

Проблема определения версии Windows 11

Многие разработчики, работающие с Delphi и Free Pascal, сталкиваются с проблемой: функция RtlGetNtVersionNumbers из ntdll.dll возвращает для Windows 11 те же значения, что и для Windows 10 (major version = 10, minor version = 0), хотя сборка (build number) отличается. Это связано с тем, что Microsoft продолжает использовать номер версии 10.0 для Windows 11, изменяя только номер сборки.

Решение через номер сборки

Самый простой способ определить Windows 11 - проверить номер сборки:

program DetectWindows11;

{$APPTYPE CONSOLE}

uses
  Windows;

procedure RtlGetNtVersionNumbers(out MajorVersion, MinorVersion, BuildNumber: DWORD); 
  stdcall; external 'ntdll.dll';

function IsWindows11OrNewer: Boolean;
var
  Major, Minor, BuildNumber: DWORD;
begin
  RtlGetNtVersionNumbers(Major, Minor, BuildNumber);
  // Извлекаем номер сборки (младшие 16 бит)
  BuildNumber := BuildNumber and $FFFF;
  Result := (Major = 10) and (Minor = 0) and (BuildNumber >= 22000);
end;

begin
  if IsWindows11OrNewer then
    Writeln('Это Windows 11 или новее')
  else
    Writeln('Это Windows 10 или старше');
  Readln;
end.

Альтернативные методы определения версии

1. Использование Win32Proc (Lazarus)

В Lazarus можно использовать модуль Win32Proc из LCL:

uses
  Win32Proc;

function GetWindowsVersionName: string;
begin
  case WindowsVersion of
    wv95:     Result := 'Windows 95';
    wvNT4:    Result := 'Windows NT 4.0';
    // ... другие версии
    wv10:     Result := 'Windows 10';
    wv11:     Result := 'Windows 11';
  else
    Result := 'Неизвестная версия Windows';
  end;
end;

Важно: Для корректной работы необходимо включить манифест в настройках проекта.

2. Чтение из реестра

Можно получить информацию из реестра:

function GetWindowsVersionFromRegistry: string;
var
  Reg: TRegistry;
begin
  Result := 'Неизвестная версия';
  Reg := TRegistry.Create;
  try
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    if Reg.OpenKeyReadOnly('SOFTWARE\Microsoft\Windows NT\CurrentVersion') then
    begin
      Result := Reg.ReadString('ProductName');
      Reg.CloseKey;
    end;
  finally
    Reg.Free;
  end;
end;

3. Использование WMI

Более надежный, но сложный способ через WMI:

uses
  ComObj, Variants, SysUtils;

function GetWindowsVersionFromWMI: string;
var
  FSWbemLocator: OleVariant;
  FWMIService: OleVariant;
  FWbemObjectSet: OleVariant;
  FWbemObject: OleVariant;
  oEnum: IEnumVariant;
  iValue: LongWord;
begin
  Result := 'Неизвестная версия';
  try
    FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
    FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
    FWbemObjectSet := FWMIService.ExecQuery('SELECT Caption FROM Win32_OperatingSystem', 'WQL', 0);
    oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
    if oEnum.Next(1, FWbemObject, iValue) = 0 then
    begin
      Result := FWbemObject.Caption;
      FWbemObject := Unassigned;
    end;
  except
    on E: Exception do
      Result := 'Ошибка: ' + E.Message;
  end;
end;

Почему RtlGetNtVersionNumbers возвращает Windows 10?

Microsoft решила сохранить совместимость, оставив для Windows 11 тот же основной номер версии (10.0), что и у Windows 10. Различие только в номере сборки:

  • Windows 10: build number < 22000
  • Windows 11: build number ≥ 22000

Первая версия Windows 11 имела номер сборки 22000, последующие обновления увеличивают этот номер.

Рекомендации по определению версии Windows

  1. Для простых проверок используйте сравнение номера сборки через RtlGetNtVersionNumbers.
  2. Для точного определения названия версии используйте WMI или чтение из реестра.
  3. В Lazarus-приложениях удобно использовать модуль Win32Proc.
  4. Не полагайтесь только на номер версии для проверки возможностей системы - лучше проверять наличие конкретных API-функций.

Пример полной программы

program WindowsVersionDetector;

{$APPTYPE CONSOLE}

uses
  SysUtils, Windows, Registry;

procedure RtlGetNtVersionNumbers(out MajorVersion, MinorVersion, BuildNumber: DWORD); 
  stdcall; external 'ntdll.dll';

function IsWindows11OrNewer: Boolean;
var
  Major, Minor, Build: DWORD;
begin
  RtlGetNtVersionNumbers(Major, Minor, Build);
  Build := Build and $FFFF;
  Result := (Major = 10) and (Minor = 0) and (Build >= 22000);
end;

function GetWindowsVersionFromRegistry: string;
var
  Reg: TRegistry;
  CurrentBuild: string;
begin
  Result := 'Неизвестная версия Windows';
  Reg := TRegistry.Create;
  try
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    if Reg.OpenKeyReadOnly('SOFTWARE\Microsoft\Windows NT\CurrentVersion') then
    begin
      Result := Reg.ReadString('ProductName');
      CurrentBuild := Reg.ReadString('CurrentBuild');
      Reg.CloseKey;

      if Pos('Windows 10', Result) > 0 then
      begin
        if StrToIntDef(CurrentBuild, 0) >= 22000 then
          Result := 'Windows 11 (обнаружено по номеру сборки)';
      end;
    end;
  finally
    Reg.Free;
  end;
end;

var
  Major, Minor, Build: DWORD;
begin
  RtlGetNtVersionNumbers(Major, Minor, Build);
  Build := Build and $FFFF;

  Writeln(Format('Версия ядра: %d.%d.%d', [Major, Minor, Build]));
  Writeln('По RtlGetNtVersionNumbers: ', 
    IfThen(IsWindows11OrNewer, 'Windows 11 или новее', 'Windows 10 или старше'));
  Writeln('По реестру: ', GetWindowsVersionFromRegistry);

  Readln;
end.

Заключение

Хотя Microsoft изменила подход к нумерации версий Windows, разработчики на Delphi и Free Pascal могут точно определить версию ОС, используя либо номер сборки, либо альтернативные методы. Для большинства случаев достаточно проверки номера сборки через RtlGetNtVersionNumbers, но если требуется точное название продукта, лучше использовать WMI или реестр.

Создано по материалам из источника по ссылке.

статья описывает методы определения версии Windows 11 в Delphi и Pascal, когда стандартная функция RtlGetNtVersionNumbers возвращает данные для Windows 10.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Windows ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-06-04 06:12:50/0.0058689117431641/0