Liste Thread-IDs zu einem Prozeß (32Bit)

    • Offizieller Beitrag

    Gewissermaßen als "Nebenprodukt" für eine Problemlösung brauchte ich die einem Prozeß zugehörigen Thread-IDs.
    Vielleicht kann es noch jemand anders gebrauchen.

    Edit:
    - Habe die Hilfsfunktionen jetzt in die Funktion eingebunden.
    - Bug bei Integerrückgabe gefixt

    _GetThreadsList
    [autoit]

    #include <Array.au3>
    $a = _GetThreadsList('autoit3.exe')
    ;~ $a = _GetThreadsList('autoit3.exe', 0) ; Thread-IDs als Integer
    _ArrayDisplay($a)

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ; Function Name....: _GetThreadsList
    ; Description......: Gibt alle Thread-IDs zu einem übergebenen Prozeß zurück
    ; Parameter(s).....: $vPID Prozeß-ID/-Name, dessen Thread-IDs ermittelt werden sollen
    ; $fHex Rückgabe der Thread-IDs als 8-stellige Hexzahl (True=Standard) od. Integer
    ; Return Value(s)..: Erfolg
    ; Ein 2D-Array, [0][0] enthält Anzahl der Threads, [0][1] die PID
    ; [n][0] = Thread-ID, [n][1] = Kernel base priority level des Threads.
    ; Die Priorität ist eine Zahl von 0 bis 31, wobei 0 der kleinst möglichen Threadpriorität entspricht.
    ; Fehler
    ; 0 @error=1 Prozeß nicht vorhanden
    ; -1 @error=Fehlerwert DllCall DllCall fehlgeschlagen
    ; Author(s)........: BugFix ([email='bugfix@autoit.de'][/email])
    ;===============================================================================
    Func _GetThreadsList($vPID, $fHex=True)
    If Not IsNumber($vPID) Then
    Local $pL = ProcessList($vPID)
    If Not IsArray($pL) Then Return SetError(1,0,0)
    $vPID = $pL[1][1]
    EndIf
    Local Const $TH32CS_SNAPTHREAD = 0x00000004
    Local $ret, $SnapProcHandle, $NextProc, $TThreadEntry, $sThreads = '', $aTmp, $aCol, $thID
    Local $tTHREADENTRY32 = DllStructCreate( _
    'DWORD dwSize;' & _
    'DWORD cntUsage;' & _
    'DWORD th32ThreadID;' & _
    'DWORD th32OwnerProcessID;' & _
    'LONG tpBasePri;' & _
    'LONG tpDeltaPri;' & _
    'DWORD dwFlags;')
    DllStructSetData($tTHREADENTRY32, 'dwSize', DllStructGetSize($tTHREADENTRY32))
    $ret = DllCall('Kernel32.dll', 'int', 'CreateToolhelp32Snapshot', 'dword', $TH32CS_SNAPTHREAD, 'dword', 0)
    If @error Then Return SetError(@error,0,-1)
    $SnapProcHandle = $ret[0]
    $ret = DllCall('Kernel32.dll', 'int', 'Thread32First', 'hwnd', $SnapProcHandle, 'ptr', DllStructGetPtr($tTHREADENTRY32))
    If @error Then Return SetError(@error,0,-1)
    $NextProc = $ret[0]
    While $NextProc
    If DllStructGetData($tTHREADENTRY32, 'th32OwnerProcessID') = $vPID Then
    $thID = DllStructGetData($tTHREADENTRY32, 'th32ThreadID')
    If $fHex Then $thID = Hex($thID, 8)
    $sThreads &= $thID & Chr(1) & String(DllStructGetData($tTHREADENTRY32, 'tpBasePri')) & @LF
    EndIf
    Local $ret = DllCall('Kernel32.dll', 'int', 'Thread32Next', 'hwnd', $SnapProcHandle, 'ptr', DllStructGetPtr($tTHREADENTRY32))
    If @error Then Return SetError(@error,0,-1)
    $NextProc = $ret[0]
    WEnd
    $aTmp = StringSplit(StringTrimRight($sThreads, 1), @LF)
    Local $aOut[$aTmp[0]+1][2] = [[0,$vPID]]
    For $i = 1 To $aTmp[0]
    $aCol = StringSplit($aTmp[$i], Chr(1), 2)
    $aOut[$i][0] = $aCol[0]
    $aOut[$i][1] = $aCol[1]
    $aOut[0][0] += 1
    Next
    Return $aOut
    EndFunc ;==>_GetThreadsList

    [/autoit]
  • Ich denke du hast das schließen dieses Handles

    [autoit]

    $ret = DllCall('Kernel32.dll', 'int', 'CreateToolhelp32Snapshot', 'dword', $TH32CS_SNAPTHREAD, 'dword', 0)

    [/autoit]

    vergessen ;)

    Also einfach ans Ende:

    [autoit]

    DllCall($hKernel, "bool", "CloseHandle", "hwnd", $ret[0])

    [/autoit]

    €:
    Ich hatte auch mal solch eine Funktion gemacht :P

    Spoiler anzeigen
    [autoit]

    Func _GetProcessThreads($iPID)
    Local $hThreadSnap, $aTID[1], $i = 0, $hThreadFirst, $hThreadNext, $iCount = 0, $iUBound
    Local Const $szTe32Data = "dword dwSize;dword cntUsage;dword th32ThreadId;dword th32OwnerProcessID;long tpBasePri;long tpDeltaPri;dword dwFlags"
    Local $szTE32 = DLLStructCreate($szTe32Data)
    Local $hKernel = DllOpen("kernel32.dll")
    $hThreadSnap = DllCall($hKernel, "ptr", "CreateToolhelp32Snapshot", "dword", 0x00000004, "dword", 0)
    If @error Then
    DllCall($hKernel, "bool", "CloseHandle", "hwnd", $hThreadSnap[0])
    Return SetError(-1)
    EndIf
    DllStructSetData($szTE32, "dwSize", DllStructGetSize($szTE32))
    $hThreadFirst = DllCall($hKernel, "bool", "Thread32First", "ptr", $hThreadSnap[0], "ptr", DLLStructGetPtr($szTE32))
    If @error Then
    DllCall($hKernel, "bool", "CloseHandle", "hwnd", $hThreadSnap[0])
    Return SetError(-2)
    EndIf
    If $hThreadFirst[0] = True Then
    Do
    If DLLStructGetData($szTE32, "th32OwnerProcessID") = $iPID Then
    If Not $i = 0 Then
    $iUBound = UBound($aTID)
    ReDim $aTID[$iUBound + 1]
    EndIf
    $aTID[$i] = DLLStructGetData($szTE32, "th32ThreadId")
    $i += 1
    ReDim $aTID[$i]
    EndIf
    $hThreadNext = DllCall($hKernel, "bool", "Thread32Next", "ptr", $hThreadSnap[0], "ptr", DLLStructGetPtr($szTE32))
    Until $hThreadNext[0] = False
    EndIf
    DllCall($hKernel, "bool", "CloseHandle", "hwnd", $hThreadSnap[0])
    DllClose($hKernel)
    $szTE32 = 0
    Return $aTID
    EndFunc

    [/autoit]