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

Получить путь к EXE по дескриптору окна

Delphi , Программа и Интерфейс , EXE файл

Получить путь к EXE по дескриптору окна

Оформил: DeeCo
Автор: http://www.swissdelphicenter.ch

uses
   PsAPI, TlHelp32;
 // portions by Project Jedi www.delphi-jedi.org/ 
const
   RsSystemIdleProcess = 'System Idle Process';
   RsSystemProcess = 'System Process';

 function IsWinXP: Boolean;
 begin
   Result := (Win32Platform = VER_PLATFORM_WIN32_NT) and
     (Win32MajorVersion = 5) and (Win32MinorVersion = 1);
 end;

 function IsWin2k: Boolean;
 begin
   Result := (Win32MajorVersion >= 5) and
     (Win32Platform = VER_PLATFORM_WIN32_NT);
 end;

 function IsWinNT4: Boolean;
 begin
   Result := Win32Platform = VER_PLATFORM_WIN32_NT;
   Result := Result and (Win32MajorVersion = 4);
 end;

 function IsWin3X: Boolean;
 begin
   Result := Win32Platform = VER_PLATFORM_WIN32_NT;
   Result := Result and (Win32MajorVersion = 3) and
     ((Win32MinorVersion = 1) or (Win32MinorVersion = 5) or
     (Win32MinorVersion = 51));
 end;

 function RunningProcessesList(const List: TStrings; FullPath: Boolean): Boolean;

   function ProcessFileName(PID: DWORD): string;
   var
     Handle: THandle;
   begin
     Result := '';
     Handle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PID);
     if Handle <> 0 then
       try
         SetLength(Result, MAX_PATH);
         if FullPath then
         begin
           if GetModuleFileNameEx(Handle, 0, PChar(Result), MAX_PATH) > 0 then
             SetLength(Result, StrLen(PChar(Result)))
           else
             Result := '';
         end
         else
         begin
           if GetModuleBaseNameA(Handle, 0, PChar(Result), MAX_PATH) > 0 then
             SetLength(Result, StrLen(PChar(Result)))
           else
             Result := '';
         end;
       finally
         CloseHandle(Handle);
       end;
   end;

   function BuildListTH: Boolean;
   var
     SnapProcHandle: THandle;
     ProcEntry: TProcessEntry32;
     NextProc: Boolean;
     FileName: string;
   begin
     SnapProcHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
     Result := (SnapProcHandle <> INVALID_HANDLE_VALUE);
     if Result then
       try
         ProcEntry.dwSize := SizeOf(ProcEntry);
         NextProc := Process32First(SnapProcHandle, ProcEntry);
         while NextProc do
         begin
           if ProcEntry.th32ProcessID = 0 then
           begin
             // PID 0 is always the "System Idle Process" but this name cannot be 
            // retrieved from the system and has to be fabricated. 
            FileName := RsSystemIdleProcess;
           end
           else
           begin
             if IsWin2k or IsWinXP then
             begin
               FileName := ProcessFileName(ProcEntry.th32ProcessID);
               if FileName = '' then
                 FileName := ProcEntry.szExeFile;
             end
             else
             begin
               FileName := ProcEntry.szExeFile;
               if not FullPath then
                 FileName := ExtractFileName(FileName);
             end;
           end;
           List.AddObject(FileName, Pointer(ProcEntry.th32ProcessID));
           NextProc := Process32Next(SnapProcHandle, ProcEntry);
         end;
       finally
         CloseHandle(SnapProcHandle);
       end;
   end;

   function BuildListPS: Boolean;
   var
     PIDs: array [0..1024] of DWORD;
     Needed: DWORD;
     I: Integer;
     FileName: string;
   begin
     Result := EnumProcesses(@PIDs, SizeOf(PIDs), Needed);
     if Result then
     begin
       for I := 0 to (Needed div SizeOf(DWORD)) - 1 do
       begin
         case PIDs[I] of
           0:
             // PID 0 is always the "System Idle Process" but this name cannot be 
            // retrieved from the system and has to be fabricated. 
            FileName := RsSystemIdleProcess;
           2:
             // On NT 4 PID 2 is the "System Process" but this name cannot be 
            // retrieved from the system and has to be fabricated. 
            if IsWinNT4 then
               FileName := RsSystemProcess
             else
               FileName := ProcessFileName(PIDs[I]);
             8:
             // On Win2K PID 8 is the "System Process" but this name cannot be 
            // retrieved from the system and has to be fabricated. 
            if IsWin2k or IsWinXP then
               FileName := RsSystemProcess
             else
               FileName := ProcessFileName(PIDs[I]);
             else
               FileName := ProcessFileName(PIDs[I]);
         end;
         if FileName <> '' then
           List.AddObject(FileName, Pointer(PIDs[I]));
       end;
     end;
   end;
 begin
   if IsWin3X or IsWinNT4 then
     Result := BuildListPS
   else
     Result := BuildListTH;
 end;

 function GetProcessNameFromWnd(Wnd: HWND): string;
 var
   List: TStringList;
   PID: DWORD;
   I: Integer;
 begin
   Result := '';
   if IsWindow(Wnd) then
   begin
     PID := INVALID_HANDLE_VALUE;
     GetWindowThreadProcessId(Wnd, @PID);
     List := TStringList.Create;
     try
       if RunningProcessesList(List, True) then
       begin
         I := List.IndexOfObject(Pointer(PID));
         if I > -1 then
           Result := List[I];
       end;
     finally
       List.Free;
     end;
   end;
 end;

Перевод на русский язык:

Это код Delphi, который извлекает путь к исполняемому файлу, связанному с данным окном (Wnd) на операционных системах Windows.

Функция GetProcessNameFromWnd принимает в качестве входного параметра HWND (Handle to Window) и возвращает путь к исполняемому файлу, связанному с этим окном. Если окно не существует или не запущено, она вернет пустую строку.

Работа функции происходит следующим образом:

  1. Она проверяет, является ли входное Wnd валидным окном с помощью IsWindow. Если это не валидное окно, она сразу возвращает результат.
  2. Затем она использует GetWindowThreadProcessId для получения идентификатора процесса (PID) потока, владеющего этим окном. Это даст нам PID процесса, запускаемого исполняемым файлом, связанным с этим окном.
  3. Далее она создает пустой список строк List.
  4. Затем она вызывает функцию RunningProcessesList для получения списка всех запущенных процессов. Эта функция использует два различных метода: либо вызывает CreateToolhelp32Snapshot и перебирает процессы с помощью Process32First и Process32Next, либо использует EnumProcesses для получения массива PIDs.
  5. Если PID, полученный в шаге 2, совпадает с одним из PID в списке, она находит соответствующий путь к исполняемому файлу в списке и возвращает его.

Функция RunningProcessesList имеет два варианта: BuildListTH использует CreateToolhelp32Snapshot для получения снимка всех запущенных процессов, а BuildListPS использует EnumProcesses для получения массива PIDs. Выбор между этими двумя методами зависит от версии Windows.

Функция ProcessFileName принимает PID в качестве входного параметра и возвращает путь к исполняемому файлу, связанному с этим PID. Если процесс запущен под Win2k или XP, она использует GetModuleFileNameEx для получения полного пути модуля (исполняемого файла). В противном случае она использует GetModuleBaseNameA для получения основного имени модуля.

Вот альтернативное решение, использующее только один метод и не используя CreateToolhelp32Snapshot и EnumProcesses:

function GetProcessNameFromWnd(Wnd: HWND): string;
var
  PID: DWORD;
begin
  Result := '';
  if IsWindow(Wnd) then
  begin
    PID := INVALID_HANDLE_VALUE;
    GetWindowThreadProcessId(Wnd, @PID);
    if PID <> INVALID_HANDLE_VALUE then
      Result := ProcessFileName(PID);
  end;
end;

function ProcessFileName(PID: DWORD): string;
var
  Handle: THandle;
begin
  Result := '';
  Handle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PID);
  if Handle <> 0 then
  try
    SetLength(Result, MAX_PATH);
    if GetModuleFileNameEx(Handle, 0, PChar(Result), MAX_PATH) > 0 then
      SetLength(Result, StrLen(PChar(Result)));
  finally
    CloseHandle(Handle);
  end;
end;

Альтернативное решение использует только функцию ProcessFileName для извлечения пути к исполняемому файлу, связанному с данным PID. Она открывает handle к процессу с помощью OpenProcess, затем вызывает GetModuleFileNameEx для получения полного пути модуля (исполняемого файла). Если вызов успешен, она устанавливает длину строки Result в фактическую длину возвращенного пути. Наконец, она закрывает handle с помощью CloseHandle.

Получение пути к EXE- файлу по дескриптору окна.


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

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




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


:: Главная :: EXE файл ::


реклама


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

Время компиляции файла: 2024-12-22 20:14:06
2025-07-02 02:16:43/0.0038750171661377/0