Arrayfehler in Funktion

  • Prinzipiell hab ich meine Funktion fertig, nur gibt es einen Fehler den ich nicht erkenne:
    Wenn man bei $iMode 2 angibt, gibt es einen Error beim StringRegExp, dass es kein Array ist, obwohl ich es mir mit _ArrayDisplay anschauen kann.
    Any thoughts?

    [autoit]


    #include-once
    #include <Array.au3>
    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _ProcessGetModules
    ; Description....: Retrieves the currently loaded modules in the target process.
    ; Syntax.........: _ProcessGetModules($iPID, $iMode)
    ; Parameters.....: $iPID - The PID of the target process.
    ; $iMode - 1: Retrieves an array with the fullpath of the modules.
    ; 2: Retrieves an array with the modules only.
    ; Return values..: Success - An array with the loaded modules.
    ; Failure - Empty array
    ; Author.........: [email='pinguin94@autoit.de'][/email]
    ; Modified.......: -
    ; Remarks........: Array.au3 needed
    ; Related........: None
    ; Link...........: None
    ; Example........: No
    ; ===============================================================================================================================
    Func _ProcessGetModules($iPID, $iMode = 1)
    Local $aModules[1], $aTemp

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

    Local $Kernel32 = DllOpen("kernel32.dll")
    Local $PsAPI = DllOpen("psapi.dll")

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

    Local $hOpen = DllCall($Kernel32, "hwnd", "OpenProcess", "int", BitOR(0x0400, 0x0010), "int", 0, "int", $iPID)
    $hOpen = $hOpen[0]
    Local $Struct = DllStructCreate("int[1024]")
    $aEnum = DllCall($PsAPI, "int", "EnumProcessModules", "hwnd", $hOpen, "ptr", DllStructGetPtr($Struct), "int", DllStructGetSize($Struct), "int*", 0)
    $iMax = $aEnum[4] / 4
    For $i = 1 To $iMax
    $aTemp = DllCall($PsAPI, "int", "GetModuleFileNameEx", "hwnd", $hOpen, "int", DllStructGetData($Struct, 1, $i), "str", "", "int", 2048)
    If $aTemp[3] > "" Then
    Switch $iMode
    Case 1
    _ArrayAdd($aModules, $aTemp[3])
    Case 2
    $RegExp = StringRegExp($aTemp[3], "\\(\w*).dll", 3) ;Soll alle .dll filtern <-- Error!
    _ArrayAdd($aModules, $RegExp[0] & ".dll")
    EndSwitch
    EndIf
    Next
    DLLCall($Kernel32, "int", "CloseHandle", "int",$hOpen)
    DllClose($Kernel32)
    DllClose($PsAPI)

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

    Return $aModules
    EndFunc

    [/autoit]

    Verbesserungen an der Funktion nehm ich gerne an, die werden direkt umgesetzt.
    Vielleicht braucht die Funktion ja wer, damit kann man super Task Manager programmieren, der direkt schaut, welche module geladen sind! :D

    MfG

  • Bei welchem Durchlauf von der For-Schleife geht er denn auf Error? Und dann zähl mal die _ArrayDisplay-Fenster.
    Habs.

    Spoiler anzeigen
    [autoit]

    #include-once
    #include <Array.au3>

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _ProcessGetModules
    ; Description....: Retrieves the currently loaded modules in the target process.
    ; Syntax.........: _ProcessGetModules($iPID, $iMode)
    ; Parameters.....: $iPID - The PID of the target process.
    ; $iMode - 1: Retrieves an array with the fullpath of the modules.
    ; 2: Retrieves an array with the modules only.
    ; Return values..: Success - An array with the loaded modules.
    ; Failure - Empty array
    ; Author.........: [email='pinguin94@autoit.de'][/email]
    ; Modified.......: -
    ; Remarks........: Array.au3 needed
    ; Related........: None
    ; Link...........: None
    ; Example........: No
    ; ===============================================================================================================================
    Func _ProcessGetModules($iPID, $iMode = 1)
    Local $aModules[1], $aTemp

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

    Local $Kernel32 = DllOpen("kernel32.dll")
    Local $PsAPI = DllOpen("psapi.dll")

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

    Local $hOpen = DllCall($Kernel32, "hwnd", "OpenProcess", "int", BitOR(0x0400, 0x0010), "int", 0, "int", $iPID)
    $hOpen = $hOpen[0]
    Local $Struct = DllStructCreate("int[1024]")
    $aEnum = DllCall($PsAPI, "int", "EnumProcessModules", "hwnd", $hOpen, "ptr", DllStructGetPtr($Struct), "int", DllStructGetSize($Struct), "int*", 0)
    $iMax = $aEnum[4] / 4
    For $i = 1 To $iMax
    $aTemp = DllCall($PsAPI, "int", "GetModuleFileNameEx", "hwnd", $hOpen, "int", DllStructGetData($Struct, 1, $i), "str", "", "int", 2048)
    If $aTemp[3] > "" Then
    Switch $iMode
    Case 1
    _ArrayAdd($aModules, $aTemp[3])
    Case 2
    $RegExp = StringRegExp($aTemp[3], "\\(\w*).dll", 3) ;Soll alle .dll filtern <-- Error!
    If Not @error Then _ArrayAdd($aModules, $RegExp[0] & ".dll")
    EndSwitch
    EndIf
    Next
    $aModules[0] = UBound($aModules) - 1
    DLLCall($Kernel32, "int", "CloseHandle", "int",$hOpen)
    DllClose($Kernel32)
    DllClose($PsAPI)

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

    Return $aModules
    EndFunc

    [/autoit]


    Das erste Element im Array ist ja leer, da steht ja kein Pfad drin, also kann StringRegExp nix finden.
    Und damit das leere Element kein Platz verschwendet, hab ich das mal so gemacht, dass er die Anzahl der Module reinschreibt ;).


    Noch was: Hab da ganze mal getestet mit Firefox, da gibt er mir bei Mode 1 136 Module und bei Mode 2 120 Module raus, wieso?

    2 Mal editiert, zuletzt von m-obi (13. Oktober 2010 um 07:28)

  • ... ohne Array.au3
    [autoit]

    #include-once

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _ProcessGetModules
    ; Description....: Retrieves the currently loaded modules in the target process.
    ; Syntax.........: _ProcessGetModules($iPID, $iMode)
    ; Parameters.....: $iPID - The PID of the target process.
    ; $iMode - 1: Retrieves an array with the fullpath of the modules.
    ; 2: Retrieves an array with the modules only.
    ; Return values..: Success - An array with the loaded modules.
    ; Failure - Empty array
    ; Author.........: [email='pinguin94@autoit.de'][/email]
    ; Modified.......: -
    ; Remarks........: No Array.au3 needed
    ; Related........: None
    ; Link...........: None
    ; Example........: No
    ; ===============================================================================================================================
    Func _ProcessGetModules($iPID, $iMode = 1)

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

    Switch $iMode
    Case 1, 2
    Case Else
    Return SetError(1, 0, 0)
    EndSwitch

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

    Local $Kernel32 = DllOpen("kernel32.dll")
    Local $PsAPI = DllOpen("psapi.dll")

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

    Local $hOpen = DllCall($Kernel32, "handle", "OpenProcess", "int", 0x0400 + 0x0010, "int", 0, "int", $iPID)
    Local $Struct = DllStructCreate("int[1024]")
    Local $aEnum = DllCall($PsAPI, "int", "EnumProcessModules", "handle", $hOpen[0], "ptr", DllStructGetPtr($Struct), "int", DllStructGetSize($Struct), "int*", 0)
    Local $iMax = $aEnum[4] / 4
    Local $aModules[$iMax + 1]
    Local $aTemp, $i, $iMod = 0
    For $i = 1 To $iMax
    $aTemp = DllCall($PsAPI, "int", "GetModuleFileNameEx", "handle", $hOpen[0], "int", DllStructGetData($Struct, 1, $i), "str", "", "int", 2048)
    If $aTemp[3] > "" Then
    $iMod += 1
    Switch $iMode
    Case 1
    $aModules[$i] = $aTemp[3]
    Case Else
    $aModules[$i] = StringMid($aTemp[3], StringInStr($aTemp[3], "\", 0, -1) + 1)
    EndSwitch
    EndIf
    Next
    $aModules[0] = $iMod
    DLLCall($Kernel32, "int", "CloseHandle", "handle", $hOpen[0])

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

    DllClose($Kernel32)
    DllClose($PsAPI)

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

    Return $aModules
    EndFunc

    [/autoit]
  • Hi!


    Habe deine Func ein wenig erweitert _ProcessGetModulesEx

    Spoiler anzeigen
    [autoit]

    #include-once
    #include <_ArrayMultiDisplay.au3>

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _ProcessGetModules
    ; Description....: Retrieves the currently loaded modules in the target process.
    ; Syntax.........: _ProcessGetModules($iPID, $iMode)
    ; Parameters.....: $iPID - The PID of the target process.
    ; $iMode - 1: Retrieves an array with the fullpath of the modules.
    ; 2: Retrieves an array with the modules only.
    ; $FilterFlag - The filter criteria. This parameter can be one of the following values
    ; - 1: List the 32-bit modules.
    ; - 2: List the 64-bit modules.
    ; - 3: List all modules.
    ; - 0: Use the default behavior.
    ; Return values..: Success - An array with the loaded modules.
    ; Failure - Empty array
    ; Author.........: [email='pinguin94@autoit.de'][/email], Großvater, Kleiner
    ; Modified.......: -
    ; Remarks........: No Array.au3 needed
    ; Related........: None
    ; Link...........: None
    ; Example........: No
    ; ===============================================================================================================================

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

    Global Const $LIST_MODULES_32BIT = 0x01 ; Liste der 32-Bit-Module.
    Global Const $LIST_MODULES_64BIT = 0x02 ; Liste der 64-Bit-Module.
    Global Const $LIST_MODULES_ALL = 0x03 ; Liste aller Module.
    Global Const $LIST_MODULES_DEFAULT = 0x0 ; Verwenden Sie das Standardverhalten.

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

    Dim $aP = ProcessList()
    Dim $aP
    For $i = 1 To UBound($aP) - 1
    $aPrEx = _ProcessGetModulesEx($aP[$i][1],1,3)
    _ArrayMultiDisplay($aPrEx)
    Next

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

    Func _ProcessGetModulesEx($iPID, $iMode = 1, $FilterFlag = 0)
    If ProcessExists($iPID) Then
    Switch $iMode
    Case 1, 2
    Case Else
    Return SetError(1, 0, 0)
    EndSwitch
    Local $Kernel32 = DllOpen('kernel32.dll')
    Local $PsAPI = DllOpen('psapi.dll')
    Local $hOpen = DllCall($Kernel32, "handle", "OpenProcess", "int", 0x0400 + 0x0010, "int", 0, "int", $iPID)
    Local $Struct = DllStructCreate("int[1024]")
    Local $aEnum = DllCall($PsAPI, 'int', 'EnumProcessModulesEx', 'handle', $hOpen[0], 'ptr', DllStructGetPtr($Struct), 'int', DllStructGetSize($Struct), 'int*', 0, 'dword', $FilterFlag)
    Local $iMax = $aEnum[4] / 4
    Local $aModules[$iMax + 1]
    Local $aTemp, $i, $iMod = 0
    For $i = 1 To $iMax
    $aTemp = DllCall($PsAPI, 'int', 'GetModuleFileNameEx', 'handle', $hOpen[0], 'int', DllStructGetData($Struct, 1, $i), 'str', '', 'int', 2048)
    If $aTemp[3] > "" Then
    $iMod += 1
    Switch $iMode
    Case 1
    $aModules[$i] = $aTemp[3]
    Case Else
    $aModules[$i] = StringMid($aTemp[3], StringInStr($aTemp[3], '\', 0, -1) + 1)
    EndSwitch
    EndIf
    Next
    $aModules[0] = $iMod
    DllCall($Kernel32, 'int', 'CloseHandle', 'handle', $hOpen[0])
    DllClose($Kernel32)
    DllClose($PsAPI)
    Return $aModules
    EndIf
    Return SetError(1, 0, -1)
    EndFunc ;==>_ProcessGetModulesEx

    [/autoit]

    LG Kleiner

  • Sehr gut :)

    Aber war es jetzt so nötig in EnumProcessModulesEx, einfach nur ein $iFlag mit zu übergeben? :P
    Wäre ja jetzt nicht so die Hürde für einen, der noch mehr will eben das Flag hinzuzufügen. Aber gut ich glaub ich stell die UDF mal rein in den Skripte Bereích mit special thanks an euch :D

    Hab mal Thread auf gelöst gesetzt ;)