Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Как узнать имя файла по handle окна?


Автор: Voyager 3.2.2006, 05:49
GetWindowThreadProcessId(FindWindow('MyClass', nil);, @ProcessId);
HandleWindow := OpenProcess(PROCESS_ALL_ACCESS, False, ProcessId);

В общем есть handle окна приложения, получаемый через FindWindow, есть ProcessId и т.д. Как узнать путь до ехе-файла/имя файла приложения?


Автор: _hunter 3.2.2006, 11:32
делаеш CreateToolhelp32Snapshot
потом Process32First / Process32Next и сравниваеш твой ProcessId с PROCESSENTRY32.th32ProcessID как найдеш -- смотри PROCESSENTRY32.szExeFile

Автор: Voyager 3.2.2006, 12:30
Да, этот способ я знаю, он даст имя ехе. А вот как узнать расположение этого ехе, то есть путь до файла?

Автор: _hunter 3.2.2006, 13:03
он даст полный путь
Добавлено @ 13:12
+ сюда:
http://forum.vingrad.ru/index.php?showtopic=22908
глянь...

Автор: RA 3.2.2006, 14:57
Цитата(_hunter @ 3.2.2006, 13:03 Найти цитируемый пост)

он даст полный путь


Как когда-то писал посол ....

Цитата

Смотри описание CreateToolhelp32Snapshot
Process32First / Process32Next
Там по поводу имени исполняемого файла сказано:Цитата
szExeFile
Pointer to a null-terminated string that specifies the name of the executable file for the process.
Windows 2000/XP:  The file name does not include the path.

Windows 95/98/Me:  The file name includes the path.
Т.е. получается наоборот - в 2k/XP имя .exe будет без пути...


Добавлено @ 15:11
однако не всё безнадёжно.
http://forum.vingrad.ru/index.php?showtopic=11700&view=findpost&p=74829

Автор: Girder 3.2.2006, 16:07
Цитата(RAdmin @ 3.2.2006, 14:57 Найти цитируемый пост)

однако не всё безнадёжно.
Получаеш PID процесса по окну... после чего можеш получить и имя и путь, и параметры запуска http://forum.vingrad.ru/index.php?findpost=289762

Автор: RA 3.2.2006, 20:06
Я не знаю правильно ли я был понят smile (я хотел сказать что лехкая переработка кода данного послом привидёт к нужному результату)
так что чтоб потом небыло недопониманий мне пришлось написать то что я имел в виду smile :

Код

uses Tlhelp32 
.....
var

    WindowName: Integer;
  ProcessId: Integer;
  
.......

procedure TForm1.Button1Click(Sender: TObject);
var
 ssh1, ssh2 : THandle;
 pe32 : TProcessEntry32;
 me32 : TModuleEntry32;


begin
  WindowName := FindWindow(nil, pChar(Edit1.text));

  GetWindowThreadProcessId(WindowName, @ProcessId);



         ssh1 := CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
         pe32.dwSize := SizeOf(pe32);
         me32.dwSize := SizeOf(me32);

   if Process32First(ssh1, pe32) then
   repeat

       ssh2 := CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, pe32.th32ProcessID);
       if Module32First(ssh2, me32) then
       repeat

         if me32.th32ProcessID = ProcessID then
         Memo1.lines.add( me32.szExePath );

       until not Module32Next(ssh2, me32);
       CloseHandle(ssh2);


   until not Process32Next(ssh1, pe32);
      CloseHandle(HandleWindow);


end;





Получаем полный путь к процессу + все подключённые к ниму модули.

Автор: Voyager 3.2.2006, 21:32
Спасибо, разобрался (переделал немного вариант Girder'a):
Код

var
  GCL,DW,StrAddr,NumWriteRead:Cardinal;
  OFPCommandLineA:string='';
...
GetWindowThreadProcessId(FindWindow('MyClass', nil);, @ProcessId);
HandleWindow := OpenProcess(PROCESS_ALL_ACCESS, False, ProcessId);
                                    If HandleWindow<>0 then
                                        begin
                                            GCL:=Cardinal(GetProcAddress(GetModuleHandle('kernel32.dll'),'GetCommandLineA'));
                                            if GCL<>0 then
                                                begin
                                                    if ReadProcessMemory(HandleWindow,Pointer(GCL+1),@DW,4,NumWriteRead)and(NumWriteRead=4)and
                                                    ReadProcessMemory(HandleWindow,Pointer(DW),@StrAddr,4,NumWriteRead)and(NumWriteRead=4) then
                                                        begin
                                                            SetString(OFPCommandLineA, nil, MAX_PATH);
                                                                if ReadProcessMemory(HandleWindow,Pointer(StrAddr),@OFPCommandLineA[1],Length(OFPCommandLineA),NumWriteRead) then
                                                                    SetLength(OFPCommandLineA,Pos(#0,OFPCommandLineA)-1)
                                                                else
                                                                    OFPCommandLineA:='';
                                                        end;
                                                end;
                                            CloseHandle(HandleWindow);
                                        end;

В OFPCommandLineA будет полный путь с параметрами.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)