
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.97.14.82] |
![]() |
|
Сообщ.
#1
,
|
|
|
Доброго дня! Коллеги, пытаюсь на Delphi XE3 и XE7 получить имя процесса по его PID.
Нашел несколько вариантов как это сделать: 1). сделать OpenProcess, а дальше GetModuleFileNameEx 2). использовать GetProcessImageFileName Первый вариант работает для обычных приложений, но при попытке получить имя процесса браузера (Chrome, например), получаю ошибку: System error. Code: 299. Запрос ReadProcessMemory или WriteProcessMemory был выполнен только частично. Код как получаю: ![]() ![]() var AppPath: String; WinH: THandle; PrId: Cardinal; hProcess: THandle; path: array[0..MAX_PATH - 1] of char; cProcName:array[0..MAX_PATH] of Char; begin WinH:= GetForegroundWindow; GetWindowThreadProcessID(WinH, @PrId); hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, PrID); if hProcess <> 0 then try if GetModuleFileNameEx(hProcess, 0, path, MAX_PATH) = 0 then RaiseLastOSError; AppPath := path; Edit5.Text:= AppPath; finally CloseHandle(hProcess) end else RaiseLastOSError; Что касается второго способа, то для него пришлось объявить: ![]() ![]() function GetProcessImageFileName(hProcess:THandle; lpImageFileName:LPTSTR; nSize:DWORD):DWORD; stdcall; external 'PSAPI.dll' name 'GetProcessImageFileNameW'; И использование: ![]() ![]() if GetProcessImageFileName(PrId,@cProcName,MAX_PATH) <> 0 then //SizeOf(cProcName)); begin AppPath := cProcName; Edit6.Text:= AppPath; end else showmessage(SysErrorMessage(GetLastError())); Но возвращает функция всегда 0. Сообщение об ошибке "Неверный дескриптор". В обоих случаях не могу сообразить, как исправить положение (( Мне нужно починить любой из способов, который сможет выдавать имя процесса для любого из приложений, в том числе браузеров. Буду благодарен совету по сути вопроса. |
Сообщ.
#2
,
|
|
|
Возможно стоит использовать вот этот способ
![]() ![]() function GetModuleNameByPID(PID: Integer): String; var h: THANDLE; e: TPROCESSENTRY32; begin Result := '<not found>'; h := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if h <> INVALID_HANDLE_VALUE then begin if Process32First(h, e) then repeat if e.th32ProcessID = PID then begin Result := copy(e.szExeFile, Length(e.szExeFile)); break; end; until not Process32Next(h, e); CloseHandle(h); end; end; |
Сообщ.
#3
,
|
|
|
macomics, благодарю за ответ. Но к сожалению, этот код завершается на строке:
if Process32First(h, e) then repeat Process32First возвращает false. |
Сообщ.
#4
,
|
|
|
Тогда попробуйте константу TH32CS_SNAPALL
|
Сообщ.
#5
,
|
|
|
Цитата macomics @ к сожалению, аналогично. Уточню, что выполняю приложение на Вин 7 х64. Использование дальнейшее предполагается на Win 10-11 |
Сообщ.
#6
,
|
|
|
У меня на Win 7 x64 этот способ отлично работал. Вы уверены, что у вас в системе нету программ, которые скрывают свое присутствие от taskmgr. Этим способом taskmgr получает список процессов. Он должен работать.
|
![]() |
Сообщ.
#7
,
|
|
SilverShield, во втором случае ты передаёшь в GetProcessImageFileName первым параметром PID, а надо handle. Т.е. тебе нужно сначала открыть процесс (как в первом случае) и полученный дескриптор передать в эту ф-цию.
Но в любом случае, чтобы получать имена всех (почти) процессов, твоя прога должна быть запущена с правами админа. |
Сообщ.
#8
,
|
|
|
Цитата SilverShield @ if Process32First(h, e) then repeat Process32First возвращает false. Надо установить поле e.dwSize = sizeof( PROCESSENTRY32 ) Taking a Snapshot and Viewing Processes |
Сообщ.
#9
,
|
|
|
Цитата ЫукпШ @ Надо установить поле e.dwSize = sizeof( PROCESSENTRY32 ) Спасибо, что уточнили. По памяти написал функцию - мой недочет. Рабочий вариант: ![]() ![]() function GetModuleNameByPID(PID: Integer): String; var h: THANDLE; e: TPROCESSENTRY32; begin Result := '<not found>'; h := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if h <> INVALID_HANDLE_VALUE then begin e.dwSize := SizeOf(TPROCESSENTRY32); if Process32First(h, e) then repeat if e.th32ProcessID = PID then begin Result := copy(e.szExeFile, Length(e.szExeFile)); break; end; until not Process32Next(h, e); CloseHandle(h); end; end; |
Сообщ.
#10
,
|
|
|
Цитата Krid @ во втором случае ты передаёшь в GetProcessImageFileName первым параметром PID, а надо handle. Благодарю! С дескриптором работает! macomics, ЫукпШ, благодарю! Этот вариант тоже работает как надо! Вопрос решен! |