<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; AutoHotkey: получение дополнительной инфы о процессах]]></title>
		<link>https://forum.script-coding.com/viewtopic.php?id=174</link>
		<atom:link href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=174&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «AutoHotkey: получение дополнительной инфы о процессах».]]></description>
		<lastBuildDate>Sat, 21 Jul 2007 17:33:28 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: AutoHotkey: получение дополнительной инфы о процессах]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=3587#p3587</link>
			<description><![CDATA[<p>Исправлена пара недосмотров. Спасибо <strong>YMP</strong>&#039;у, его справедливые замечания можно посмотреть <a href="http://forum.script-coding.com/viewtopic.php?id=556">здесь</a></p>]]></description>
			<author><![CDATA[null@example.com (Androgen)]]></author>
			<pubDate>Sat, 21 Jul 2007 17:33:28 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=3587#p3587</guid>
		</item>
		<item>
			<title><![CDATA[Re: AutoHotkey: получение дополнительной инфы о процессах]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=817#p817</link>
			<description><![CDATA[<p>Исправлено имя переменной Path на pPath (и текущая версия скрипта - 1.1).<br />Основания: если в скрипе, вызывающем функцию GetModuleFileNameEx, отсутствовала директива #NoEnv, функция возвращала значение переменной окружения %Path%.<br />Исправления внесены в пост #1.</p>]]></description>
			<author><![CDATA[null@example.com (Androgen)]]></author>
			<pubDate>Wed, 11 Oct 2006 04:20:12 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=817#p817</guid>
		</item>
		<item>
			<title><![CDATA[AutoHotkey: получение дополнительной инфы о процессах]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=788#p788</link>
			<description><![CDATA[<p>Средства для работы с процессами в AutoHotkey довольно удобны, а синтаксис прост и логичен (что в AHK бывает далеко не всегда). И всё же кое-чего не хватает. Вот скажем, нужно вам перезапустить к-либо процесс. Убить-то вы его убили, а вот как запустить, если путь к исполнимому файлу вам заранее неизвестен? Или вы думаете, что известен, но на этом компе он (путь) другой? Как узнать путь к exe-шнику процесса? Или даже так: и путь вам известен, и на этом компе он верный, но процесс был запущен с некими параметрами командной строки. И если вы этот процесс перезапустите без них (параметров), то получите совсем не тот результат, на который рассчитываете.<br />А вот другая ситуация: я тут недавно столкнулся с тем, что в справке к WinRar&#039;у не описаны параметры для распаковки сразу нескольких архивов за один раз. Но сам-то WinRar из контекстного меню это делает! Как? Ну, узнать это просто: даем РАРу команду из контекстного меню распаковать несколько архивов. Архивы берем побольше, чтобы РАР работал подольше <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" />. Он начинает распаковывать, а мы не торопясь открываем Process Explorer ( <a href="http://www.sysinternals.com/Utilities/ProcessExplorer.html">http://www.sysinternals.com/Utilities/P … lorer.html</a> ) и смотрим, какую же командную строку создал WinRar сам себе. Всё, теперь мы обладатели недокументированной фичи WinRar&#039;а и можем распаковывать сразу толпу архивов одним экземпляром РАРа. Классно. Но что, если прога отрабатывает свои действия так быстро, что мы не успеваем метнуться в Process Explorer? Или мы хотим делать эти действия не &quot;руками&quot;, а скриптом?<br />Вот для таких целей я и предлагаю пару функций. <strong>Первая функция позволяет узнать путь к экзешнику процесса, а вторая - получить целиком командную строку для процесса.</strong> Эти функции я выдрал из мега скрипта <strong>shimanov</strong>&#039;а <a href="http://www.autohotkey.com/forum/viewtopic.php?t=9000">http://www.autohotkey.com/forum/viewtopic.php?t=9000</a>. Я их слегка модернизировал-упростил и прокомментировал. Функции непростые, поэтому, если найдете ошибки - дайте знать.<br /><strong>На самом деле, область применения этих функций значительно шире, чем может показаться на первый взгляд</strong>, поэтому присмотритесь.<br /><strong><span style="color: blue">Исправлено 11.10.2006 до версии 1.1</span></strong><br /></p><div class="codebox"><pre><code>;*******************************************************************************
; AutoHotkey Version:   1.0.44.09+
; Автор:                Androgen Belkin
; Имя скрипта:          GetExtProccessInfo().ahk (v.1.1)
;*******************************************************************************
; Функции для:
; 1. Получения пути к исполнимому файлу процесса
; 2. Получения командной строки для процесса
; Известные ограничения:
; а) не удается получить доступ к некоторым (немногим) системным процессам,
;    в этом случае функции возвращают пустую строку
; б) функции, возможно, не будут работать в линейке WIN 9x, но я не проверял
;*******************************************************************************

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

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

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

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

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

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

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

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

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

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

    Return_2: ; метка перехода к закрытию хэндла
    DllCall( &quot;CloseHandle&quot;, &quot;UInt&quot;, hp_target ) ; закрываем хэндл
    Return, result ; возвращаем полную командную строку для PID&#039;а процесса
} ; конец функции
;-------------------------------------------------------------------------------------------------------------</code></pre></div><p><span style="color: blue">Пара примеров применения:</span><br /></p><div class="codebox"><pre><code>; Откройте какой-нибудь файл в Блокноте, и запустите пример.
; Заголовок окна Блокнота изменится и будет содержать полный путь к открытому в нем файлу.
#Include C:\GetExtProccessInfo().ahk ; путь к скрипту с функциями

ID_Notepad := WinExist( &quot;ahk_class Notepad&quot; ) ; получаем ID Блокнота
If NOT ID_Notepad ; если Блокнот не найден...
{
    MsgBox, Блокнот не запущен!
    ExitApp ; конец скрипта
}
WinGet, PID_Target, PID, ahk_id %ID_Notepad% ; получаем PID найденного окна Блокнота
Exe_Path := GetModuleFileNameEx( PID_Target ) ; вызываем функцию получения пути процесса Блокнота
If NOT Exe_Path ; если что-то не так...
{
    MsgBox, Процесс не существует, или к нему нет доступа
    ExitApp ; конец скрипта
}
Com_Line := GetRemoteCommandLine( PID_Target ) ; вызываем функцию получения ком. строки Блокнота
If NOT Com_Line ; если что-то не так...
{
    MsgBox, Процесс не существует, или к нему нет доступа
    ExitApp ; конец скрипта
}
StringReplace, File_Path, Com_Line, %Exe_Path% ; удаляем из строки путь к Блокноту
StringReplace, File_Path, File_Path, &quot;,, All ; удаляем из строки все кавычки, если они есть
File_Path = %File_Path% ; избавляемся от возможных пробелов в начале строки
WinSetTitle, ahk_id %ID_Notepad%,, %File_Path% - Блокнот ; вписываем путь в заголовок окна Блокнота
WinActivate ; активируем окно Блокнота</code></pre></div><div class="codebox"><pre><code>; А вот пример получения информации о некоторых процессах
#Include C:\GetExtProccessInfo().ahk ; путь к скрипту с функциями

; Process, Exist, AutoHotkey.exe
Process, Exist, svchost.exe
; Process, Exist, Totalcmd.exe
PID_Target := ErrorLevel ; в ErrorLevel содержится PID процесса
If NOT PID_Target
{
    MsgBox, Процесс не существует
    ExitApp
}
Exe_Path := GetModuleFileNameEx( PID_Target ) ; вызываем функцию получения пути процесса
If NOT Exe_Path ; если что-то не так...
{
    MsgBox, Процесс не существует, или к нему нет доступа
    ExitApp ; конец скрипта
}
Com_Line := GetRemoteCommandLine( PID_Target ) ; вызываем функцию получения ком. строки процесса
If NOT Com_Line ; если что-то не так...
{
    MsgBox, Процесс не существует, или к нему нет доступа
    ExitApp ; конец скрипта
}
MsgBox, Exe_Path: %Exe_Path%`nCom_Line: %Com_Line%</code></pre></div><p><span style="color: blue"><strong>Исправил одну строчку:</strong></span></p><div class="codebox"><pre><code>success := DllCall( &quot;ReadProcessMemory&quot;, &quot;UInt&quot;, hp_target, &quot;UInt&quot;, pCommandLine, &quot;UInt&quot;, &amp;result, &quot;UInt&quot;, buffer_size, &quot;UInt&quot;, 0 )</code></pre></div><p>на<br /></p><div class="codebox"><pre><code>DllCall( &quot;ReadProcessMemory&quot;, &quot;UInt&quot;, hp_target, &quot;UInt&quot;, pCommandLine, &quot;UInt&quot;, &amp;result, &quot;UInt&quot;, buffer_size, &quot;UInt&quot;, 0 )</code></pre></div><p>Это просто неподчищенный результат тестов. На работу скрипта это никак не влияет, но я всё же решил её исправить, чтобы не путала: скрипт и так не из простых.</p>]]></description>
			<author><![CDATA[null@example.com (Androgen)]]></author>
			<pubDate>Fri, 06 Oct 2006 19:16:40 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=788#p788</guid>
		</item>
	</channel>
</rss>
