Kleines Problem beim filtern von Arrays

  • Hallo,

    ich bin neu hier, hab aber mir immer schonmal Hilfe in diesem Forum erlesen können. Nun hab ich ein Problemchen, bei dem ich nicht wirklich weiterkomme und auch Google nix verwertbares mehr ausspuckt.
    Und zwar habe ich ein Script ein klein wenig versucht abzuändern.
    Es handelt sich dabei um eine Simple GUI, die alle laufenden Prozesse anzeigt.
    Nun dachte ich mir, das man anhand einer Liste die Systemprozesse von Win ausblenden könnte.
    Das hat soweit auch ganz gut geklappt.

    Ich kann doppelte Einträge (z.B. svchost.exe) aus dem Array löschen und andere Prozesse werden auch ausgefiltert. Allerdings besteht das Problem, das bei den doppelten oder auch mehrfach vorhandenen Prozessen, mir weiterhin ein Prozess angezeigt wird.
    Ich hänge mal mein Script an, evtl. kann mir einer weiter helfen.

    Spoiler anzeigen
    [autoit]


    #Include <GUIConstants.au3> ;Includes the information that allows you to create windows and controls
    #Include <ArrayMore.au3>
    Dim $string [ 1 ]
    Dim $newProcesses[1]
    $Window = GUICreate ( "Process Inspector" , 528 , 258 + 25 ) ;The main window
    $List = GUICtrlCreateList ( "" , 2 , 2 , 524 , 262 ) ;Creates a large white box which lists strings in it
    $ButtonRefresh = GUICtrlCreateButton ( "Refresh" , 30 , 260 , 462 , 20 )
    GUISetState ( ) ;Enables your window so its visible

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

    While 1
    $msg = GUIGetMsg ( )
    If $msg = $GUI_EVENT_CLOSE Then Exit
    If $msg = $ButtonRefresh Then
    GUICtrlDelete ( $List ) ;Recreates the list to
    $List = GUICtrlCreateList ( "" , 2 , 2 , 524 , 262 ) ;quickly clear the data
    Global $Processes = ProcessList ( )
    ;##################################
    ;Hier wird meine Funktion aufgerufen

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

    $newProcesses = _DeleteSysProcesses($Processes)
    ;##################################

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

    For $iCC = 1 To UBound ( $newProcesses ) - 1
    $sLoadList = 'Process: ' & $newProcesses [ $iCC ] [ 0 ]
    GUICtrlSetData ( $List , $sLoadList )
    Next
    EndIf
    WEnd

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

    Func _DeleteSysProcesses(ByRef $newArray)
    _Array2DDblDel($newArray)
    ; Hier nun die Liste, könnte man später auch aus einer INI auslesen
    DIM $Error [ 7 ]
    $Error[0] = 'svchost.exe'
    $Error[1] = 'smss.exe'
    $Error[2] = 'dllhost.exe'
    $Error[3] = 'dwm.exe'
    $Error[4] = 'spoolsv.exe'
    $Error[5] = 'csrss.exe'
    $Error[6] = 'winlogon.exe'

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

    For $i = 0 To UBound($Error) -1
    $iIndex = _ArraySearch($newArray, $Error[$i], 0, 0, 0, 1, 0)
    If $iIndex Then
    _Array2DDelete($newArray, $iIndex)
    Endif
    Next
    Return $newArray

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

    EndFunc

    [/autoit]
  • Hi

    Du erstellst jedesmal in der Schleife die Globale Variable neu - das sollte im gesammten Script jedoch nur indgesammt 1 Mal geschehen.
    Auch kannst du den Inhalt der Listbox löschen, anstatt des ganzen Controls (und wieder neu erzeugen).

    Ich würde das in etwa so machen:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>

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

    Global $oDict_List = ObjCreate('Scripting.Dictionary')
    If Not IsObj($oDict_List) Then
    MsgBox(0, "ERROR", "creating scripting.dictionary object failed")
    Exit
    EndIf
    $oDict_List.CompareMode = 1

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

    Global $oDict_System = ObjCreate('Scripting.Dictionary')
    If Not IsObj($oDict_System) Then
    MsgBox(0, "ERROR", "creating scripting.dictionary object failed")
    Exit
    EndIf
    $oDict_System.CompareMode = 1
    $oDict_System.Add('svchost.exe', 1)
    $oDict_System.Add('smss.exe', 1)
    $oDict_System.Add('dllhost.exe', 1)
    $oDict_System.Add('dwm.exe', 1)
    $oDict_System.Add('spoolsv.exe', 1)
    $oDict_System.Add('csrss.exe', 1)
    $oDict_System.Add('winlogon.exe', 1)

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

    Opt("GUIOnEventMode", 1)

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

    Global $hGui = GUICreate("Process Inspector", 528, 258 + 25)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    Global $cList = GUICtrlCreateList("", 2, 2, 524, 262)
    Global $cButtonRefresh = GUICtrlCreateButton("Refresh", 30, 260, 462, 20)
    GUICtrlSetOnEvent($cButtonRefresh, "_Refresh")
    GUISetState()

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

    While 1
    Sleep(100)
    WEnd

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

    Func _Refresh()
    Local $aProcess = ProcessList()
    If @error Or Not IsArray($aProcess) Then Return False
    $oDict_List.RemoveAll
    For $i = 1 To $aProcess[0][0]
    If $oDict_System.Exists($aProcess[$i][0]) Then ContinueLoop
    If Not $oDict_List.Exists($aProcess[$i][0]) Then $oDict_List.Add($aProcess[$i][0], $aProcess[$i][0])
    Next
    GUICtrlSetData($cList, "")
    For $i In $oDict_List.Keys()
    GUICtrlSetData($cList, "Process: " & $i)
    Next
    EndFunc ;==>_Refresh

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

    Func _Exit()
    Exit
    EndFunc ;==>_Exit

    [/autoit]

    Die Scripting.Dictionary-Objekte arbeiten schneller, als wenn man ein normales Array durchgehen muß - besonders, wenn die Liste immer länger wird

    E

  • Vielen dank für die schnelle Antwort. Werd ich dann zu Hause mal ausprobieren.
    Ich muss zugeben das ich mich das Erste mal mit sowas probiere. Habe sonst mehr einfachere Sachen mit. Autoit gemacht. Da hab ich mal wieder was hilfreches dazu lernen können.

    Danke

    //Edit:

    So, bin jetzt zu Hause und hab das Script von "eukalyptus" mal testen können. Funktioniert wirklich einwandfrei das ganze.

    Danke noch einmal

    2 Mal editiert, zuletzt von cryp0r (3. August 2011 um 15:57) aus folgendem Grund: Jetzt getestet