seominho 发表于 2009-4-8 16:22:39

有没有办法通过PID 获取进程名??

如何通过PID或者 别的参数 获取进程名啊??

[ 本帖最后由 seominho 于 2009-4-8 16:58 编辑 ]

sensel 发表于 2009-4-8 16:48:06

_ProcessGetName

seominho 发表于 2009-4-8 17:16:36

回复 2# sensel 的帖子

有没有办法 可以获取 某个进程的 子进程??

sensel 发表于 2009-4-8 17:27:46

额,,,子进程。。。这就复杂了
提供一个思路:用API或WMI遍历进程获取父进程名,如果父进程名符合条件,增加进程ID到数组。
通过API或OBJ,几乎没有做不到的。

pusofalse 发表于 2009-4-8 18:03:13

$tagProcessEntry =        "dword dwSize;dword cntUsage;" & _
                "dword th32ProcessID;ulong_ptr th32DefaultHeapID;" & _
                "dword th32ModuleID;dword cntThreads;" & _
                "dword th32ParentProcessID;long pcPriClassBase;" & _
                "dword dwFlags;char szExeFile"

Func _CreateToolhelp32Snapshot($iProcessId, $iFlag)
        Local $hSnap
        $iProcessId = ProcessExists($iProcessId)

        $hSnap = DllCall("kernel32.dll", "hWnd", "CreateToolhelp32Snapshot", _
                        "dword", $iFlag, "dword", $iProcessId)
        Return $hSnap
EndFunc        ;==>_CreateToolhelp32Snapshot()


Func _Process32First($hSnap)
        Local $tProcessEntry = DllStructCreate($tagProcessEntry)
        DllStructSetData($tProcessEntry, 1, DllStructGetSize($tProcessEntry))

        DllCall("kernel32.dll", "int", "Process32First", _
                        "hWnd", $hSnap, _
                        "ptr", DllStructGetPtr($tProcessEntry))
        Return $tProcessEntry
EndFunc        ;==>_Process32First()


Func _Process32Next(ByRef $hSnap, ByRef $tProcessEntry)
        Local $iResult
        $iResult = DllCall("kernel32.dll", "int", "Process32Next", _
                        "hWnd", $hSnap, _
                        "ptr", DllStructGetPtr($tProcessEntry))
        Return SetError(Not $iResult, 0, $iResult)
EndFunc        ;==>_Process32Next()

Func _CloseHandle($hWnd)
        Local $iResult = DllCall("kernel32.dll", "int", "CloseHandle", "hWnd", $hWnd)
        Return $iResult <> 0
EndFunc        ;==>_CloseHandle()


Func _EnumChildProcesses($iProcessId)
        Local $hSnap, $tProcessEntry, $aResult

        $hSnap = _CreateToolhelp32Snapshot(0, 2)
        $tProcessEntry = _Process32First($hSnap)
        $iProcessId = ProcessExists($iProcessId)
        If not $iProcessId Then Return SetError(@error, 0, 0)
        While True
                _Process32Next($hSnap, $tProcessEntry)
                If @error Then ExitLoop
                $iProcess = DllStructGetData($tProcessEntry, "th32ProcessID")
                $iParent = DllStructGetData($tProcessEntry, "th32ParentProcessID")
                If $iParent = $iProcessId Then
                        $aResult = $iProcess
                        Redim $aResult
                EndIf
        WEnd
        $tProcessEntry = 0
        _CloseHandle($hSnap)
        If Ubound($aResult) = 1 Then Return SetError(2, 0, 0)
        Redim $aResult
        Return SetError(0, Ubound($aResult), $aResult)
EndFunc        ;==>_EnumChildProcesses()

$aChild = _EnumChildProcesses("smss.exe")
For $o = 0 to ubound($aChild) - 1
        msgbox(1, '', $aChild[$o])
Next

sensel 发表于 2009-4-8 18:23:04

回复 5# pusofalse 的帖子

优美的代码。学习了,谢谢!

seominho 发表于 2009-4-9 09:42:30

回复 5# pusofalse 的帖子

:face (29): 学习了。。。。。 谢了! 呵呵

seominho 发表于 2009-4-9 13:53:15

回复 5# pusofalse 的帖子

为什么这个 DllStructGetSize($tProcessEntry)是0 啊??
所以下面的DLLCall返回值 都是0!!!!!!

seominho 发表于 2009-4-9 14:13:25

回复 5# pusofalse 的帖子

啊!! 好了。。。。 打错了个字呵呵

sensel 发表于 2009-4-12 03:19:36

回复 5# pusofalse 的帖子

小改一下代码,让返回数组类似于ProcessList函数返回值,同时包含进程名称与进程ID。

#Include <Array.au3>

Local $aChild = _EnumChildProcesses("explorer.exe")
_ArrayDisplay($aChild)
Exit

;===============================================================================
; 说明:   枚举子进程
; 语法:   _EnumChildProcesses($iPID)
; 参数:   $iPID - 进程名称或ID
; 需要:   无
; 返回:   成功 - 二维数组, 结构类似于 ProcessList 函数返回值
;         失败 - 空字符 "", 并设置 @error 到
;            1 - 进程不存在
;            2 - 子进程未找到
; 备注:   参考: http://www.autoitx.com/forum.php?mod=viewthread&tid=6284
;===============================================================================
Func _EnumChildProcesses($iPID)
        Local $hSnap, $tProcessEntry, $iParent, $iProcess, $sExeFile, $aResult = []

        $iPID = ProcessExists($iPID)
        If $iPID = 0 Then Return SetError(1, 0, "")
        $hSnap = _CreateToolhelp32Snapshot(0, 2)
        $tProcessEntry = _Process32First($hSnap)

        While 1
                _Process32Next($hSnap, $tProcessEntry)
                If @error Then ExitLoop

                $iParent = DllStructGetData($tProcessEntry, "th32ParentProcessID")
                If $iParent = $iPID Then
                        $sExeFile = DllStructGetData($tProcessEntry, "szExeFile")
                        $iProcess = DllStructGetData($tProcessEntry, "th32ProcessID")

                        $aResult += 1
                        ReDim $aResult[$aResult + 1]
                        $aResult[$aResult] = $sExeFile
                        $aResult[$aResult] = $iProcess
                EndIf
        WEnd

        _CloseHandle($hSnap)
        If $aResult = 0 Then
                Return SetError(2, 0, "")
        Else
                Return $aResult
        EndIf
EndFunc   ;==>_EnumChildProcesses

Func _CreateToolhelp32Snapshot($iPID, $iFlag)
        Local $hSnap

        $hSnap = DllCall("kernel32.dll", "hWnd", "CreateToolhelp32Snapshot", "dword", $iFlag, "dword", $iPID)
        Return $hSnap
EndFunc   ;==>_CreateToolhelp32Snapshot

Func _Process32First($hSnap)
        Local $tagProcessEntry, $tProcessEntry

        $tagProcessEntry = "dword dwSize;dword cntUsage;" & _
                "dword th32ProcessID;ulong_ptr th32DefaultHeapID;" & _
                "dword th32ModuleID;dword cntThreads;" & _
                "dword th32ParentProcessID;long pcPriClassBase;" & _
                "dword dwFlags;char szExeFile"
        $tProcessEntry = DllStructCreate($tagProcessEntry)
        DllStructSetData($tProcessEntry, 1, DllStructGetSize($tProcessEntry))

        DllCall("kernel32.dll", "int", "Process32First", "hWnd", $hSnap, "ptr", DllStructGetPtr($tProcessEntry))
        Return $tProcessEntry
EndFunc   ;==>_Process32First

Func _Process32Next(ByRef $hSnap, ByRef $tProcessEntry)
        Local $iResult

        $iResult = DllCall("kernel32.dll", "int", "Process32Next", "hWnd", $hSnap, "ptr", DllStructGetPtr($tProcessEntry))
        Return SetError(NOT $iResult, 0, $iResult)
EndFunc   ;==>_Process32Next

Func _CloseHandle($hWnd)
        Local $iResult

        $iResult = DllCall("kernel32.dll", "int", "CloseHandle", "hWnd", $hWnd)
        Return $iResult <> 0
EndFunc   ;==>_CloseHandle

pusofalse 发表于 2009-4-12 03:42:13

绕了弯路了,用WMI获取子进程要简洁的多。
#include <Array.au3>

$aChild = _EnumChildProcesses("explorer.exe")
_ArrayDisplay($aChild)

Func _EnumChildProcesses($iProcessId)
        Local $oProcess, $oParent, $aResult, $sWMI

        $iProcessId = ProcessExists($iProcessId)
        $sWMI = "Select * From Win32_Process Where ParentProcessId=" & $iProcessId
        $oProcess = ObjGet("Winmgmts:\\.\root\cimv2")
        $oParent = $oProcess.ExecQuery($sWMI)
        For $ele in $oParent
                $aResult += 1
                Redim $aResult[$aResult + 1]
                $aResult[$aResult] = $ele.Name
                $aResult[$aResult] = $ele.ProcessId
        Next
        $oProcess = 0
        Return $aResult
EndFunc        ;==>_EnumChildProcesses()

sensel 发表于 2009-4-12 17:16:42

请教pusofalse,如何获取进程的完整路径?我试过用WMI,但某些进程像csrss.exe的ExecutablePath返回空值。
在下非科班出身,看Windows API操作就像看天书,没办法解决。

pusofalse 发表于 2009-4-12 19:03:30

回复 12# sensel 的帖子

获取进程的完整路径很多,用WMI的话就是用ExecutablePath。用API的话可以用你在10楼的代码,或者用GetModuleFileNameEx/QueryFullProcessImageName ,具体请参考
http://msdn.microsoft.com/en-us/library/ms683198(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms684919(VS.85).aspx
不管是api还是wmi,能获取到csrss.exe这样系统级进程的完整路径才怪。

sensel 发表于 2009-4-12 23:06:08

回复 13# pusofalse 的帖子

老大,10楼是你写的代码哦。。。我只是为了方便自己使用,加了个变量。。。
读懂你的代码花了我整整3个小时,没知识真痛苦啊:(

系统级进程?难道是用户权限阻止的?那么像Process Viewer和pv.exe之类的软件,是如何获取完整路径呢?

dd20121221 发表于 2012-4-2 23:08:04

回复 5# pusofalse


    还是P斑厉害啊
页: [1]
查看完整版本: 有没有办法通过PID 获取进程名??