Что нового

Как определить путь к образу запущенного процесса?

ViktorSPB

Новичок
Сообщения
109
Репутация
0
Добрый день.
Есть функции для работы с процессами:
ProcessExists
ProcessList
С их помощью можно определить запущен ли процесс, а также получить список всех запущенных процессов.
А как можно выудить путь к образу запущенного процесса? Ведь имя бывает одним и тем же, идентифицировать можно только по дислакации, если две одинаковые программы запущены из разных мест..
Помогите, пожалуйста, разобраться.
 
Автор
V

ViktorSPB

Новичок
Сообщения
109
Репутация
0
CreatoR, спасибо.
Уже копаю MSDN WINAPI..

Сделал, как Вы сказали, все заработало.
А у самого эта библиотека была загружена ранее и хэлп.
Спасибо еще раз большое.


Добавлено:
Сообщение автоматически объединено:

CreatoR, скажите, пожалуйста, есть ли расширенный аналог ProcessList? чтобы в массиве были пути в том числе?
Или вручную перебирать придется? Не нашел в справке..
Может, и WinList есть с указанием PID процесса?..
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
ViktorSPB [?]
есть ли расширенный аналог ProcessList? чтобы в массиве были пути в том числе?
Есть у меня вот что:

Код:
#include <Array.au3>

;============= Example with default usage =============
$aProcListEx = _ProcessListEx()

If @error Then
	MsgBox(48, "_ProcessListEx - Error", StringFormat("There was an error to get ProcessList (@error = %i)", @error))
Else
	_ArrayDisplay($aProcListEx, "_ProcessListEx Demo (All Processes)")
EndIf
;============= Example with default usage =============

;============= Example with Resource Name usage =============
$aAutoItProcList = _ProcessListEx("ProductName", "AutoIt", 0)

If @error Then
	MsgBox(48, "_ProcessListEx - Error", StringFormat("There was an error to get ProcessList (@error = %i)", @error))
Else
	_ArrayDisplay($aAutoItProcList, "_ProcessListEx Demo (AutoIt Processes)")
EndIf
;============= Example with Resource Name usage =============

;===============================================================================
;
; Function Name:  		   _ProcessListEx()
;
; Function Description:    Gets Process List with extended info, plus can retrieve only a processes with specific resources strings.
;
; Parameter(s):            $sResourceName [Optional] - Resource name of the process filename, i.e. "CompiledScript".
;                          $sInResString [Optional] - String to check in the resource name.
;                          $iWholeWord [Optional] - Defines if the $sInResString will be compared as whole string (default is 1).
;
; Requirement(s):          None.
;
; Return Value(s):         On Success -  Return 2-dimentional array, where:
;                                                                   $aRet_List[0][0] = Total processes (array elements).
;                                                                   $aRet_List[N][0] = Process Name.
;                                                                   $aRet_List[N][1] = PID (Process ID).
;                                                                   $aRet_List[N][2] = Process File Path.
;                          On Failure -  Return '' (empty string) and set @error to:
;                                                                   1 - Unable to Open Kernel32.dll.
;                                                                   2 - Unable to Open Psapi.dll.
;                                                                   3 - No Processes Found.
;
; Author(s):               G.Sandler (a.k.a MrCreatoR) - CreatoR's Lab (http://creator-lab.ucoz.ru)
;
;=====================================================================
Func _ProcessListEx($sResourceName="", $sInResString="", $iWholeWord=1)
	Local $aProcList = ProcessList()
	Local $hKernel32_Dll = DllOpen('Kernel32.dll'), $hPsapi_Dll = DllOpen('Psapi.dll')
	Local $aOpenProc, $aProcPath, $sFileVersion, $aRet_List[1][1]
	
	If $hKernel32_Dll = -1 Then Return SetError(1, 0, '')
	
	If $hPsapi_Dll = -1 Then $hPsapi_Dll = DllOpen(@SystemDir & '\Psapi.dll')
	If $hPsapi_Dll = -1 Then $hPsapi_Dll = DllOpen(@WindowsDir & '\Psapi.dll')
	If $hPsapi_Dll = -1 Then Return SetError(2, 0, '')
	
	Local $vStruct 		= DllStructCreate('int[1024]')
	Local $pStructPtr 	= DllStructGetPtr($vStruct)
	Local $iStructSize 	= DllStructGetSize($vStruct)
	
	For $i = 1 To UBound($aProcList)-1
		$aOpenProc = DllCall($hKernel32_Dll, 'hwnd', 'OpenProcess', _
			'int', BitOR(0x0400, 0x0010), 'int', 0, 'int', $aProcList[$i][1])
		
		If Not IsArray($aOpenProc) Or Not $aOpenProc[0] Then ContinueLoop
		
		DllCall($hPsapi_Dll, 'int', 'EnumProcessModules', _
			'hwnd', $aOpenProc[0], _
			'ptr', $pStructPtr, _
			'int', $iStructSize, _
			'int*', 0)
		
		$aProcPath = DllCall($hPsapi_Dll, 'int', 'GetModuleFileNameEx', _
			'hwnd', $aOpenProc[0], _
			'int', DllStructGetData($vStruct, 1), _
			'str', '', _
			'int', 2048)
		
		DllCall($hKernel32_Dll, 'int', 'CloseHandle', 'int', $aOpenProc[0])
		
		If Not IsArray($aProcPath) Or StringLen($aProcPath[3]) = 0 Then ContinueLoop
		
		$sFileVersion = FileGetVersion($aProcPath[3], $sResourceName)
		
		If $sResourceName = "" Or $sFileVersion = $sInResString Or _
			($iWholeWord = 0 And StringInStr($sFileVersion, $sInResString)) Then
			
			$aRet_List[0][0] += 1
			ReDim $aRet_List[$aRet_List[0][0]+1][3]
			$aRet_List[$aRet_List[0][0]][0] = $aProcList[$i][0] 	;Process Name
			$aRet_List[$aRet_List[0][0]][1] = $aProcList[$i][1] 	;PID (Process ID)
			$aRet_List[$aRet_List[0][0]][2] = $aProcPath[3] 		;Process File Path
		EndIf
	Next
	
	DllClose($hKernel32_Dll)
	DllClose($hPsapi_Dll)
	
	If $aRet_List[0][0] < 1 Then Return SetError(3, 0, '')
	Return $aRet_List
EndFunc



Может, и WinList есть с указанием PID процесса?
Тут нечто похожее (но это уже оффтопик, дальше либо в поиск, либо в новую тему).
 
Автор
V

ViktorSPB

Новичок
Сообщения
109
Репутация
0
Спасибо большое. С утра займусь, все просмотрю, и, если не разбирусь, создам тему. То есть через часа 4..
 
Автор
V

ViktorSPB

Новичок
Сообщения
109
Репутация
0
Creator,
доработал Вашу функцию до нужного мне результата. Может кому пригодится.
Код:
Func _MY_ProcessListEx($sResourceName="", $sInResString="", $iWholeWord=1, $iTypeSearch = 1)

#comments-start
	Перегружаемая функция!
	2 режима работы.

	Если $iTypeSearch = 1, то, независимо от $sResourceName возвращает
	массив с процессом, путь к которому вместе с именем файла указан в $sInResString
	[0][0] - количество процессов
	[n][0] - имя образа
	[n][1] - PID
	[n][2] - полный путь к образу
	
	Если $iTypeSearch = 0, то $sResourceName - имя поля файла процесса (Имя поля обычно может быть одним из:
Comments, InternalName, ProductName, CompanyName, LegalCopyright, ProductVersion,
FileDescription, LegalTrademarks, PrivateBuild, FileVersion, OriginalFilename, SpecialBuild)
	$sInResString - значение поля, по которому ищем процессы
	На выходе тот же массив

	$iWholeWord = 1 полное соответствие при поиске
	$iWholeWord = 0 частичное соответствие
#comments-end
	Local $aProcList = ProcessList()
    Local $hKernel32_Dll = DllOpen('Kernel32.dll'), $hPsapi_Dll = DllOpen('Psapi.dll')
    Local $aOpenProc, $aProcPath, $sFileVersion, $aRet_List[1][1]

    If $hKernel32_Dll = -1 Then Return SetError(1, 0, '')

    If $hPsapi_Dll = -1 Then $hPsapi_Dll = DllOpen(@SystemDir & '\Psapi.dll')
    If $hPsapi_Dll = -1 Then $hPsapi_Dll = DllOpen(@WindowsDir & '\Psapi.dll')
    If $hPsapi_Dll = -1 Then Return SetError(2, 0, '')

    Local $vStruct      = DllStructCreate('int[1024]')
    Local $pStructPtr   = DllStructGetPtr($vStruct)
    Local $iStructSize  = DllStructGetSize($vStruct)

    For $i = 1 To UBound($aProcList)-1
        $aOpenProc = DllCall($hKernel32_Dll, 'hwnd', 'OpenProcess', _
            'int', BitOR(0x0400, 0x0010), 'int', 0, 'int', $aProcList[$i][1])

        If Not IsArray($aOpenProc) Or Not $aOpenProc[0] Then ContinueLoop

        DllCall($hPsapi_Dll, 'int', 'EnumProcessModules', _
            'hwnd', $aOpenProc[0], _
            'ptr', $pStructPtr, _
            'int', $iStructSize, _
            'int*', 0)

        $aProcPath = DllCall($hPsapi_Dll, 'int', 'GetModuleFileNameEx', _
            'hwnd', $aOpenProc[0], _
            'int', DllStructGetData($vStruct, 1), _
            'str', '', _
            'int', 2048)

        DllCall($hKernel32_Dll, 'int', 'CloseHandle', 'int', $aOpenProc[0])

        If Not IsArray($aProcPath) Or StringLen($aProcPath[3]) = 0 Then ContinueLoop
		;_ArrayDisplay($aProcPath,"")
        If $iTypeSearch = 0 then $sFileVersion = FileGetVersion($aProcPath[3], $sResourceName)
		If $iTypeSearch = 1 then $sFileVersion = $aProcPath[3]

        If $iTypeSearch = 0 Then
			If $sResourceName = "" Or $sFileVersion = $sInResString Or _
				($iWholeWord = 0 And StringInStr($sFileVersion, $sInResString)) Then

				$aRet_List[0][0] += 1
				ReDim $aRet_List[$aRet_List[0][0]+1][3]
				$aRet_List[$aRet_List[0][0]][0] = $aProcList[$i][0]     ;Process Name
				$aRet_List[$aRet_List[0][0]][1] = $aProcList[$i][1]     ;PID (Process ID)
				$aRet_List[$aRet_List[0][0]][2] = $aProcPath[3]         ;Process File Path
			EndIf
		Else
			If $sFileVersion = $sInResString Or _
				($iWholeWord = 0 And StringInStr($sFileVersion, $sInResString)) Then

				$aRet_List[0][0] += 1
				ReDim $aRet_List[$aRet_List[0][0]+1][3]
				$aRet_List[$aRet_List[0][0]][0] = $aProcList[$i][0]     ;Process Name
				$aRet_List[$aRet_List[0][0]][1] = $aProcList[$i][1]     ;PID (Process ID)
				$aRet_List[$aRet_List[0][0]][2] = $aProcPath[3]         ;Process File Path
			EndIf

		EndIf
    Next

    DllClose($hKernel32_Dll)
    DllClose($hPsapi_Dll)

    If $aRet_List[0][0] < 1 Then Return SetError(3, 0, '')
    Return $aRet_List
EndFunc

Еще раз спасибо.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
ViktorSPB [?]
доработал Вашу функцию до нужного мне результата
Можно обойтись без дополнительного параметра:

Код:
#include <Array.au3>

$aProcList = _ProcessListEx(@AutoItExe)
_ArrayDisplay($aProcList)

Func _ProcessListEx($sProcess = "", $sResourceName = "", $sInResString = "", $iWholeWord = 1)
	Local $iProcFileExists, $aProcList, $aRet_List, $hKernel32_Dll, $hPsapi_Dll, $vStruct, $pStructPtr, $iStructSize, $aOpenProc, $aProcPath, $sFileVersion
	
	$iProcFileExists = FileExists($sProcess)
	
	If ProcessExists($sProcess) Then
		$aProcList = ProcessList($sProcess)
	Else
		$aProcList = ProcessList()
	EndIf
	
	Dim $aRet_List[UBound($aProcList)][3]
	$hKernel32_Dll = DllOpen('Kernel32.dll')
	$hPsapi_Dll = DllOpen('Psapi.dll')
	
	If $hKernel32_Dll = -1 Or $hPsapi_Dll = -1 Then
		Return SetError(1, 0, '')
	EndIf
	
	$vStruct = DllStructCreate('int[1024]')
	$pStructPtr = DllStructGetPtr($vStruct)
	$iStructSize = DllStructGetSize($vStruct)
	
	For $i = 1 To UBound($aProcList) - 1
		$aOpenProc = DllCall($hKernel32_Dll, 'hwnd', 'OpenProcess', 'int', BitOR(0x0400, 0x0010), 'int', 0, 'int', $aProcList[$i][1])
		
		If Not IsArray($aOpenProc) Or Not $aOpenProc[0] Then
			ContinueLoop
		EndIf
		
		DllCall($hPsapi_Dll, 'int', 'EnumProcessModules', _
			'hwnd', $aOpenProc[0], _
			'ptr', $pStructPtr, _
			'int', $iStructSize, _
			'int*', 0)
		
		$aProcPath = DllCall($hPsapi_Dll, 'int', 'GetModuleFileNameEx', _
			'hwnd', $aOpenProc[0], _
			'int', DllStructGetData($vStruct, 1), _
			'str', '', _
			'int', 2048)
		
		DllCall($hKernel32_Dll, 'int', 'CloseHandle', 'int', $aOpenProc[0])
		
		If Not IsArray($aProcPath) Or StringLen($aProcPath[3]) = 0 Then
			ContinueLoop
		EndIf
		
		$sFileVersion = FileGetVersion($aProcPath[3], $sResourceName)
		
		If $iProcFileExists Then
			If ($sProcess = $aProcPath[3]) And ($sResourceName = "" Or $sFileVersion = $sInResString Or ($iWholeWord = 0 And StringInStr($sFileVersion, $sInResString))) Then
				$aRet_List[0][0] += 1
				$aRet_List[$aRet_List[0][0]][0] = $aProcList[$i][0] ;Process Name
				$aRet_List[$aRet_List[0][0]][1] = $aProcList[$i][1] ;PID (Process ID)
				$aRet_List[$aRet_List[0][0]][2] = $aProcPath[3] ;Process File Path
			EndIf
		Else
			If $sResourceName = "" Or $sFileVersion = $sInResString Or ($iWholeWord = 0 And StringInStr($sFileVersion, $sInResString)) Then
				$aRet_List[0][0] += 1
				$aRet_List[$aRet_List[0][0]][0] = $aProcList[$i][0]
				$aRet_List[$aRet_List[0][0]][1] = $aProcList[$i][1]
				$aRet_List[$aRet_List[0][0]][2] = $aProcPath[3]
			EndIf
		EndIf
	Next
	
	DllClose($hKernel32_Dll)
	DllClose($hPsapi_Dll)
	
	ReDim $aRet_List[$aRet_List[0][0] + 1][3]
	
	If $aRet_List[0][0] < 1 Then
		Return SetError(3, 0, '')
	EndIf
	
	Return $aRet_List
EndFunc


И при чём не обязательно игнорировать параметр имени ресурса.
 

glax24

Знающий
Сообщения
72
Репутация
14
Функция
Код:
_WinAPI_GetProcessFileName()
не возвращает путь х64 программ, х32 программ путь возращается нормально.
Пробовал перед вызовом функции
Код:
Local $tValue = DllStructCreate("dword")
If @OSArch = "X64" Then
		DllCall("kernel32.dll", "int", "Wow64DisableWow64FsRedirection", "ptr", DllStructGetPtr($tValue))
EndIf

Не помогло.
Передаю на вход PID полученный с помощью
Код:
ProcessList()

Например надо узнать путь запущенного процесса opera.exe Полный путь такой
Код:
C:\Users\User\AppData\Local\Programs\Opera x64\opera.exe
Функция
Код:
_ProcessListEx()
также не возвращает пути х64 программ.
Скрипт должен быть откомпилирован только под х32.
Как решить данную проблему?
 

sngr

AutoIT Гуру
Сообщения
1,010
Репутация
408
Код:
$process='explorer.exe'
$obj = ObjGet("WinMgmts:\\.\root\cimv2")
$que = $obj.ExecQuery('SELECT * FROM Win32_Process where Caption="'&$process&'"')
$res = ''
For $o in $que
	$res = $o.ExecutablePath&@CRLF
Next
MsgBox(0,'',$res)
 

glax24

Знающий
Сообщения
72
Репутация
14
Сделал так.
Код:
Func ProcessToPathFull($NameProcess)
	Local $PathProc = ""
	Local $objWMIService = ObjGet("WinMgmts:\\.\root\cimv2")
	Local $colItems = $objWMIService.ExecQuery('SELECT * FROM Win32_Process where Caption="' & $NameProcess & '"')
	If IsObj($colItems) Then
		For $objItem In $colItems
			$PathProc = $objItem.ExecutablePath
		Next
	EndIf

	If $PathProc = "" Then
		Return SetError(1, 0, '')
	EndIf

	Return $PathProc
EndFunc
 

sngr

AutoIT Гуру
Сообщения
1,010
Репутация
408
Можно ещё сделать так, если известен pid
Код:
$pid='628'
$obj = ObjGet("WinMgmts:\\.\root\cimv2")
$que = $obj.get('Win32_Process.Handle="'&$pid&'"')
MsgBox(0,'',$que.ExecutablePath)
 

glax24

Знающий
Сообщения
72
Репутация
14
Судьба. А вы мое сообщение выше читали #7? Где описаны проблемы c программами x64.
Также
Код:
_WinAPI_GetProcessFileName()
не возвращает путь к процессу svchost.exe @error = 1
 

La2Angel

Новичок
Сообщения
156
Репутация
1
Поддерживаю тему, тоже нужно вернуть путь у х64 программ.
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
La2Angel
если сам код запускать как х64
функции в справке
 

La2Angel

Новичок
Сообщения
156
Репутация
1
Не, не, узнать адресс программы посредством функции к примеру в Windows 7 x64 при попытке узнать путь у explorer.exe*x64 он выдает путь равный - A и все.
 

BoaConstrictor-FENIX

Новичок
Сообщения
11
Репутация
1
Товарищи, я себе уже весь мозг сломал... Подскажите как при использовании конструкции:

Код:
$pid='628'
$obj = ObjGet("WinMgmts:\\.\root\cimv2")
$que = $obj.get('Win32_Process.Handle="'&$pid&'"')
MsgBox(0,'',$que.ExecutablePath)


Сделать так чтобы скрипт не завершался если текущий PID не существует???

Рассмотрю и другие варианты. Нужно получить путь к процессу в x64 системе.
 
Верх