1

Тема: AHK: Получение дополнительной инфы о процессах (Help2Ahk_L)

Из Коллекции скрипт.
Как оказалось — один из этаких краеугольных камней моего постоянно работающего.
Нужен в AHK_L виде.
Прошу не отказать.



#SingleInstance Force

1::
WinGet, PID_Target, PID, % "ahk_id " WinExist("A")
result := GetRemoteCommandLine( PID_Target )
msgbox %result%
return

;*******************************************************************************
; AutoHotkey Version:   1.0.44.09+
; Автор:                Androgen Belkin
; Имя скрипта:          GetExtProccessInfo().ahk (v.1.1)
;*******************************************************************************
; Функции для:
; 1. Получения пути к исполнимому файлу процесса
; 2. Получения командной строки для процесса
; Известные ограничения:
; а) не удается получить доступ к некоторым (немногим) системным процессам,
;    в этом случае функции возвращают пустую строку
; б) функции, возможно, не будут работать в линейке WIN 9x, но я не проверял
;*******************************************************************************

;-------------------------------------------------------------------------------------------------------------
GetModuleFileNameEx( p_pid ) ; функция получения пути к исполнимому файлу процесса (по его PID'у)
{
    h_process := DllCall( "OpenProcess", "UInt", 0x10|0x400, "Int", false, "UInt", p_pid ) ; открываем хэндл для PID процесса...
    ; ...с нужными правами (они понадобятся для GetModuleFileNameExA) и без наследования хэндла
    ; права: 0x10 = PROCESS_VM_READ, 0x400 = PROCESS_QUERY_INFORMATION
    If ( ErrorLevel OR h_process = 0 ) ; если почему-либо не удалось открыть хэндл (или он открыт для несуществующего PID'а)...
        Goto, Return_1 ; перейти к закрытию хэндла и выйти из функции

    VarSetCapacity( pPath, 259 ) ; обеспечиваем достаточную вместимость переменной (в символах, путь длиннее не бывает)
    DllCall( "psapi.dll\GetModuleFileNameExA", "UInt", h_process, "UInt", 0, "Str", pPath, "UInt", 259 ) ; получаем путь...
    ; ...для указанного хэндла процесса. GetModuleFileNameExA (ANSI), GetModuleFileNameExW (Unicode)

    Return_1: ; метка перехода к закрытию хэндла
    DllCall( "CloseHandle", h_process ) ; закрываем хэндл
    Return, pPath ; возвращаем путь к файлу процесса
} ; конец функции
;-------------------------------------------------------------------------------------------------------------

;-------------------------------------------------------------------------------------------------------------
GetRemoteCommandLine( p_pid_target ) ; функция получения командной строки для процесса (по его PID'у)
{
    hp_target := DllCall( "OpenProcess", "UInt", 0x10, "Int", false, "UInt", p_pid_target ) ; открываем хэндл для PID процесса...
    ; ...с правами для чтения 0x10 = PROCESS_VM_READ (нужны для ReadProcessMemory) и без наследования хэндла
    If ( ErrorLevel OR hp_target = 0 ) ; если почему-либо не удалось открыть хэндл (или он открыт для несуществующего PID'а)...
        Goto, Return_2 ; перейти к закрытию хэндла и выйти из функции

    hm_kernel32 := DllCall( "GetModuleHandle", "Str", "kernel32.dll" ) ; узнаем хэндл библиотеки kernel32.dll
    pGetCommandLineA := DllCall( "GetProcAddress", "UInt", hm_kernel32, "Str", "GetCommandLineA" ) ; получаем указатель...
    ; ...на адрес функции GetCommandLineA (ANSI), содержащейся в kernel32.dll

    buffer_size = 6 ; количество байт для переменной
    VarSetCapacity( buffer, buffer_size ) ; обеспечиваем достаточную вместимость переменной
    DllCall( "ReadProcessMemory", "UInt", hp_target, "UInt", pGetCommandLineA, "UInt", &buffer, "UInt", buffer_size, "UInt", 0 )
    ; для хэндла PID'а получаем перенаправление функцией GetCommandLineA на указатель на адрес командной строки...
    ; ...и кладем его по адресу "buffer" в памяти

    Loop, 4 ; преобразовываем указатель на адрес командной строки в целое число
        ppCommandLine += ( ( *( &buffer+A_Index ) ) << ( 8*( A_Index-1 ) ) ) ; создаем целое число, складывая его байты

    buffer_size = 4 ; количество байт для переменной
    VarSetCapacity( buffer, buffer_size, 0 ) ; обеспечиваем достаточную вместимость переменной, и очищаем её
    DllCall( "ReadProcessMemory", "UInt", hp_target, "UInt", ppCommandLine, "UInt", &buffer, "UInt", buffer_size, "UInt", 0 )
    ; для хэндла PID'а читаем адрес командной строки, и кладем его по адресу "buffer" в памяти

    Loop, 4 ; преобразовываем адрес в целое число
        pCommandLine += ( ( *( &buffer+A_Index-1 ) ) << ( 8*( A_Index-1 ) ) ) ; создаем целое число, складывая его байты

    ; Адрес командной строки получен, теперь извлекаем его содержимое
    buffer_size = 520 ; столько символов будем читать из командной строки (мне кажется, длиннее быть не может)
    VarSetCapacity( result, buffer_size, 1 ) ; обеспечиваем достаточную вместимость переменной, делаем её побайтной
    DllCall( "ReadProcessMemory", "UInt", hp_target, "UInt", pCommandLine, "UInt", &result, "UInt", buffer_size, "UInt", 0 )
    ; для хэндла PID'а читаем командную строку, и кладем её по адресу "result" в памяти (просто помещаем значение в переменную)

    Return_2: ; метка перехода к закрытию хэндла
    DllCall( "CloseHandle", "UInt", hp_target ) ; закрываем хэндл
    Return, result ; возвращаем полную командную строку для PID'а процесса
} ; конец функции
;-------------------------------------------------------------------------------------------------------------



^!9::exitapp

2

Re: AHK: Получение дополнительной инфы о процессах (Help2Ahk_L)

Комментарии после объявления функций надо убрать. Лучше вообще комментарии и код на одной строчке не писать, это указано в документации. А вообще способ получения командной строки очень странный, учитывая наличие документированного метода. На win7 SP1 функция имеет вид "jmp, jmp, mov", а на xp SP3 просто "mov". Так что где-то он точно работать не будет.

3

Re: AHK: Получение дополнительной инфы о процессах (Help2Ahk_L)

А где на документированный можно глянуть? Что-то не припомню...
Спасибо.

4

Re: AHK: Получение дополнительной инфы о процессах (Help2Ahk_L)

DD пишет:

А где на документированный можно глянуть? Что-то не припомню...

Недавно обсуждалось на форуме. Тут описание+ссылки на документацию, а тут пример реализации.

5

Re: AHK: Получение дополнительной инфы о процессах (Help2Ahk_L)

Как Вы находите вот такой вариант, Александр_:


F11::
WinGet, PID_Target, PID, % "ahk_id " WinExist("A")
ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process WHERE ProcessId = " . PID_Target)._NewEnum.next(x)
result := % x.CommandLine ;%
msgbox %result%
Return

Можно им удовольствоваться?

6

Re: AHK: Получение дополнительной инфы о процессах (Help2Ahk_L)

DD пишет:

Можно им удовольствоваться?

Если нужна только командная строка, то в самый раз.

7

Re: AHK: Получение дополнительной инфы о процессах (Help2Ahk_L)

Александр_ пишет:

Лучше вообще комментарии и код на одной строчке не писать, это указано в документации.

Хм, где это указано?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

8

Re: AHK: Получение дополнительной инфы о процессах (Help2Ahk_L)

teadrinker пишет:

Хм, где это указано?

Похоже я наврал, по крайней мере сейчас никаких заметок по этому поводу не нашёл... Я раньше часто сталкивался с багами из-за комментариев в самых разных местах, теперь пишу их только в уже готовых скриптах .

9

Re: AHK: Получение дополнительной инфы о процессах (Help2Ahk_L)

Возможно, проблемы были, когда после кода точка с запятой и комментарий шли без пробела. Вот пример "бага":

F1::Send,12345;Комментарий

10

Re: AHK: Получение дополнительной инфы о процессах (Help2Ahk_L)

ypppu пишет:

Возможно, проблемы были, когда после кода точка с запятой и комментарий шли без пробела.

Нет.

11

Re: AHK: Получение дополнительной инфы о процессах (Help2Ahk_L)

Александр_ пишет:

Если нужна только командная строка, то в самый раз.

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

12

Re: AHK: Получение дополнительной инфы о процессах (Help2Ahk_L)

DD пишет:

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

"x.ExecutablePath", там же была ссылка на документацию.

13

Re: AHK: Получение дополнительной инфы о процессах (Help2Ahk_L)

Спасибо Вам!