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

Ошибки при получении имени модуля в 64-битной Windows: причины и решения

Delphi , Синтаксис , Справочник по API-функциям

При разработке программного обеспечения на языке Object Pascal, особенно в среде Delphi, разработчики часто сталкиваются с различными проблемами, связанными с особенностями работы 64-битных операционных систем. Одной из таких проблем является ошибка при получении имени модуля процесса в Windows 8 и более поздних версиях, работающих в 64-битном режиме.

Вот пример функции, которая пытается получить имя модуля процесса:

function NazwaProcesu(const uchwyt: Thandle): string;
var
  pid: DWORD;
  hProcess: Thandle;
  sciezka: array [0..MAX_PATH - 1] of char;
begin
  GetWindowThreadProcessId(uchwyt, pid);
  hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, FALSE, pid);
  if hProcess <> 0 then
    try
      GetModuleFileNameEx(hProcess, 0, sciezka, MAX_PATH)
    finally
      Result := sciezka;
      CloseHandle(hProcess);
    end;
end;

На 32-битной Windows 7 данная функция работает корректно, но на 64-битной Windows 8 и выше может возвращать некорректные результаты, например, вместо ожидаемого explorer.exe возвращается мусор.

Причины проблемы

Причиной проблемы является различие в битности между приложением и целевым процессом. Функция GetModuleFileNameEx возвращает имя модуля для модулей того же битности, что и приложение. В 64-битной Windows используется эмулятор WOW64 для запуска 32-битных приложений, что может приводить к проблемам при попытке получить информацию о 64-битных процессах из 32-битного процесса и наоборот.

Решения проблемы

  1. Перекомпиляция приложения в 64-битную версию. Это позволит избежать использования эмулятора WOW64 и обеспечит корректную работу с 64-битными процессами.

  2. Использование отдельного 64-битного процесса и IPC для получения информации. Это может быть сложным решением, но оно позволит обойти проблемы с битностью.

  3. Использование WMI для получения имени модуля. WMI предоставляет более высокоуровневый интерфейс для получения информации о системе, включая имя модуля процесса.

  4. Использование функции QueryFullProcessImageName. Эта функция доступна начиная с Windows Vista и предназначена для получения полного пути к исполняемому файлу процесса.

  5. Проверка PE-заголовков. Можно использовать чтение файла в бинарном режиме и проверку на соответствие подписи PE, чтобы определить битность исполняемого файла.

Важность проверки ошибок

Необходимо всегда проверять возвращаемые функции Windows API на ошибки. В приведенном выше примере функция GetModuleFileNameEx не проверяется на ошибки, что приводит к тому, что буфер для текста остается неинициализированным и возвращает мусорные данные.

Пример исправленной функции

function NazwaProcesu(const uchwyt: Thandle): string;
type
  TQueryFullProcessImageName = function(hProcess: Thandle; dwFlags: DWORD; lpExeName: PChar; nSize: PDWORD): BOOL; stdcall;
var
  pid: DWORD;
  hProcess: Thandle;
  sciezka: array [0 .. MAX_PATH - 1] of Char;
  QueryFullProcessImageName: TQueryFullProcessImageName;
  nSize: cardinal;
begin
  Result := '';
  GetWindowThreadProcessId(uchwyt, pid);
  hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, pid);
  if hProcess <> 0 then
    try
      if GetModuleFileNameEx(hProcess, 0, sciezka, MAX_PATH) then
        if GetLastError = ERROR_SUCCESS then
          Result := sciezka
        else if Win32MajorVersion >= 6 then
        begin
          nSize := MAX_PATH;
          ZeroMemory(@sciezka, MAX_PATH);
          @QueryFullProcessImageName := GetProcAddress(GetModuleHandle('kernel32'), 'QueryFullProcessImageNameW');
          if Assigned(QueryFullProcessImageName) then
            if QueryFullProcessImageName(hProcess, 0, sciezka, @nSize) then
              Result := sciezka;
        end;
    finally
      CloseHandle(hProcess);
    end;
end;

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

Следуя этим рекомендациям, разработчики могут избежать многих проблем, связанных с получением имени модуля в 64-битных операционных системах Windows.

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

и способов решения ошибок при получении имени модуля в 64-битной Windows, возникающих при работе с функциями Windows API и влияющих на корректность работы программ на Object Pascal, особенно в среде Delphi.


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

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




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


:: Главная :: Справочник по API-функциям ::


реклама


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

Время компиляции файла: 2024-12-22 20:14:06
2025-01-13 18:58:20/0.0036921501159668/0