Dateien / Ordner rekursiv lesen

    • Offizieller Beitrag

    Hi,
    eigentlich müßte der Thread wohl zu den Scripten. Da es aber nur z. Teil von mir stammt paßt das nicht so richtig. Vielleicht läßt es sich ja auch als Beispiel in die FAQ einbinden.
    Mod's, ich vertraue euch. Ihr werdet es gegebenenfalls schon an den richtigen Ort verschieben.

    Zum Thema:
    Das rekursive Auslesen von Dateien / Ordnern wurde ja schon mehrmals angesprochen. Jos van der Zande hat dafür die prima Funktion _GetFileList( ) erschaffen.
    Ich hab diese Funktion etwas ergänzt um bei Bedarf mittels Flag aus _GetFileList ein "_GetDirList" zu machen.
    Ich hab das ganze zur Anschauung in eine GUI gepackt.
    Bitte die Beta verwenden.

    Spoiler anzeigen
    [autoit]


    #include <GUIConstants.au3>
    #Include <GuiList.au3>
    #include <file.au3>
    #Include <Misc.au3>
    #Include <GuiStatusBar.au3>
    Dim $Extension = "", $Pfad = "", $Daten[1], $arDisp[1], $currPosIndex, $file, $fileShort, $anzahl, $progress_step, $progress_val = 0
    Dim $ListPfad = @MyDocumentsDir & "\", $ListFile = "Rekursiv_List.txt", $ListFileShort = "Rekursiv_Short.txt"
    Dim $ListFileShortPrint = "Rekursiv_Short_P.txt", $a_PartsText[2] = ["", ""], $a_PartsRightEdge[2] = [40, -1], $PfadExec
    Opt("GUIOnEventMode", 1)
    $Form1 = GUICreate("Ordner- / Dateisuche (rekursiv)", 600, 458, -1, -1)
    GUISetOnEvent($GUI_EVENT_CLOSE, "AForm1Close")
    GUISetOnEvent($GUI_EVENT_SECONDARYDOWN, "SpecialEvents")
    $List1 = GUICtrlCreateList("", 24, 106, 550, 354, $WS_VSCROLL)
    GUICtrlSetOnEvent(-1, "ListClick")
    $Label1 = GUICtrlCreateLabel("Pfad:", 28, 16, 29, 17)
    $iPath = GUICtrlCreateInput("", 59, 13, 280, 21, $ES_READONLY)
    $Checkbox1 = GUICtrlCreateCheckbox("nur Ordner", 24, 47, 78, 17)
    GUICtrlSetOnEvent(-1, "ACheckbox1Click")
    $Checkbox2 = GUICtrlCreateCheckbox("ganzen Pfad zeigen", 24, 79, 130, 17)
    GUICtrlSetOnEvent(-1, "ACheckbox2Click")
    GUICtrlSetState(-1, $GUI_HIDE)
    $Checkbox3 = GUICtrlCreateCheckbox("kompletten Pfad drucken", 435, 79, 160, 17)
    GUICtrlSetState(-1, $GUI_HIDE)
    $lExtension = GUICtrlCreateLabel("Erweiterung", 185, 41, 90, 17)
    $lExtension1 = GUICtrlCreateLabel("z.B. 'exe' oder ' * '", 185, 58, 900,17)
    $iExtension = GUICtrlCreateInput("", 282, 45, 57, 21, $ES_CENTER)
    $bPath = GUICtrlCreateButton("Pfad wählen", 349, 13, 70, 21, 0)
    GUICtrlSetOnEvent(-1, "bPathClick")
    $lTipTime = GUICtrlCreateLabel("Zeit für ToolTipp:", 185, 80)
    $iTipTime = GUICtrlCreateInput ("4", 282, 77, 57, 21, $ES_CENTER)
    $updown = GUICtrlCreateUpdown($iTipTime)
    $bAuslesen = GUICtrlCreateButton("Auslesen", 349, 45, 70, 21, 0)
    GUICtrlSetOnEvent(-1, "bAuslesenClick")
    $bPrint = GUICtrlCreateButton("Drucken", 349, 77, 70, 21, 0)
    GUICtrlSetOnEvent(-1, "bPrintClick")
    $bClear = GUICtrlCreateButton("Löschen", 505, 45, 70, 21, 0)
    GUICtrlSetOnEvent(-1, "bClearClick")
    $bEnde = GUICtrlCreateButton("Ende", 505, 13, 70, 21, 0)
    GUICtrlSetOnEvent(-1, "bEndeClick")
    $StatusBar1 = _GUICtrlStatusBarCreate($Form1, $a_PartsRightEdge, $a_PartsText)
    $progressbar1 = _GUICtrlStatusBarCreateProgress($StatusBar1, 1)
    GUICtrlSetColor(-1,32250)
    GUICtrlSetState(-1, $GUI_HIDE)

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

    $Busy = GUICreate("",160,110,-1,-1,$WS_POPUP)
    GUISetBkColor(0x708090)
    $label_busy = GUICtrlCreateLabel("Einen Moment bitte." & @LF & @LF & "Die notwendigen Daten" _
    & @LF & "werden ermittelt..", 20, 15, 120, 100, $SS_CENTER)
    GUICtrlSetFont(-1, 10, Default,2)
    GUICtrlSetColor(-1, 0xF0E68C)

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

    $RightMenu = GUICreate("RightMenu", 135, 71, -1, -1, $WS_POPUP)
    $bShellEx = GUICtrlCreateButton("Datei Ausführen", 2, 2, 130, 20, 0)
    GUICtrlSetOnEvent(-1, "bShellExClick")
    $bClipboard = GUICtrlCreateButton("Copy To Clipboard", 2, 24, 130, 20, 0)
    GUICtrlSetOnEvent(-1, "bClipboardClick")
    $bEscR_Menu = GUICtrlCreateButton("Abbrechen", 2, 48, 130, 20, 0)
    GUICtrlSetOnEvent(-1, "bEscR_MenuClick")

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

    GUISetState(@SW_SHOW, $Form1)

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

    While 1
    Sleep(100)
    WEnd

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

    Func SpecialEvents()
    If @GUI_CTRLID = $GUI_EVENT_SECONDARYDOWN Then
    $ctrlfocus = ControlGetFocus($Form1,"Ordner- / Dateisuche (rekursiv)")
    If $ctrlfocus = "ListBox1" And GUICtrlRead($Checkbox2) = 1 And _
    _GUICtrlListGetText($List1, _GUICtrlListGetCaretIndex($List1)) <> "" _
    Then
    $PfadExec = _GUICtrlListGetText($List1, _GUICtrlListGetCaretIndex($List1))
    If $Extension = "n" Then
    GUICtrlSetState($bShellEx, $GUI_DISABLE)
    GUISetState(@SW_SHOW, $RightMenu)
    Else
    GUICtrlSetState($bShellEx, $GUI_ENABLE)
    GUISetState(@SW_SHOW, $RightMenu)
    EndIf
    EndIf
    EndIf
    EndFunc

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

    Func ACheckbox1Click()
    If GUICtrlRead($Checkbox1) = 1 Then
    GUICtrlSetState($lExtension,$GUI_HIDE)
    GUICtrlSetState($lExtension1,$GUI_HIDE)
    GUICtrlSetState($iExtension,$GUI_HIDE)
    Else
    GUICtrlSetState($lExtension,$GUI_SHOW)
    GUICtrlSetState($lExtension1,$GUI_SHOW)
    GUICtrlSetState($iExtension,$GUI_SHOW)
    EndIf
    EndFunc

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

    Func ACheckbox2Click()
    _GUICtrlStatusBarSetText($StatusBar1, "", 0)
    _GUICtrlStatusBarSetText($StatusBar1, "", 1)
    _GUICtrlStatusBarSetBKColor($StatusBar1, 0xD3D3D3)
    If GUICtrlRead($Checkbox2) = 1 Then
    _DisplayListLong()
    Else
    _DisplayListShort()
    EndIf
    EndFunc

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

    Func AForm1Close()
    Exit
    EndFunc

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

    Func bClearClick()
    GUICtrlSetData($iPath,"")
    GUICtrlSetData($iExtension,"")
    GUICtrlSetData($List1,"")
    GUICtrlSetState($Checkbox1, $GUI_UNCHECKED)
    GUICtrlSetState($Checkbox2, $GUI_UNCHECKED)
    GUICtrlSetState($Checkbox3, $GUI_UNCHECKED)
    GUICtrlSetState($lExtension,$GUI_SHOW)
    GUICtrlSetState($lExtension1,$GUI_SHOW)
    GUICtrlSetState($iExtension,$GUI_SHOW)
    GUICtrlSetState($Checkbox2, $GUI_HIDE)
    GUICtrlSetState($Checkbox3, $GUI_HIDE)
    _GUICtrlStatusBarSetText($StatusBar1, "", 0)
    _GUICtrlStatusBarSetText($StatusBar1, "", 1)
    _GUICtrlStatusBarSetBKColor($StatusBar1, 0xD3D3D3)
    $Pfad = ""
    $PfadExec = ""
    EndFunc

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

    Func bAuslesenClick()
    Dim $tmp = "", $asc
    If $Pfad = "" Then
    MsgBox(0, "ACHTUNG!", "Es wurde kein Pfad ausgewählt!")
    bPathClick()
    Return 0
    EndIf
    If GUICtrlRead($Checkbox1) = 1 Then
    $Extension = "n"
    Else
    $Extension = GUICtrlRead($iExtension)
    If Not StringInStr($Extension, "*") Then
    $len = StringLen($Extension)
    For $i = 1 To $len
    $asc = Asc(StringLower(StringMid($Extension,$i,1)))
    If ($asc > 47 And $asc < 58) Or ($asc > 96 And $asc < 123) Then $tmp = $tmp & StringMid($Extension,$i,1)
    Next
    $Extension = $tmp
    If StringLen($Extension) > 3 Then
    $tmp = MsgBox(4,"ACHTUNG!", "Die Erweiterung ist länger als 3 Zeichen."& @LF & @LF & " " & _
    $Extension & @LF & @LF & " Wollen Sie korrigieren?" )
    If $tmp = 6 Then
    GUICtrlSetState($iExtension, $GUI_FOCUS)
    Return 0
    EndIf
    ElseIf StringLen($Extension) = 0 Then
    MsgBox(0,"ACHTUNG!", "Die Erweiterung wurde nicht festgelegt!")
    GUICtrlSetState($iExtension, $GUI_FOCUS)
    Return 0
    EndIf
    EndIf
    EndIf
    GUISetState(@SW_SHOW, $Busy)
    _WriteAllFiles()
    GUISetState(@SW_HIDE, $Busy)
    _DisplayListShort()
    GUICtrlSetState($Checkbox2, $GUI_SHOW)
    GUICtrlSetState($Checkbox3, $GUI_SHOW)
    EndFunc

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

    Func ListClick()
    $currPosIndex = _GUICtrlListGetCaretIndex($List1)
    $info = _GUICtrlListGetText($List1, $currPosIndex)
    $tmp = StringSplit($info, "\")
    If $tmp[0] > 3 Then
    $inf1 = ""
    $inf2 = ""
    $split = Floor($tmp[0] / 2)+1
    For $i = 1 To $split
    $inf1 = $inf1 & $tmp[$i] & "\"
    Next
    For $i = $split+1 To $tmp[0]
    $inf2 = $inf2 & $tmp[$i] & "\"
    Next
    $info = $inf1 & @LF & $inf2
    EndIf
    If StringRight($info, 1) = "\" Then $info = StringTrimRight($info, 1)
    _GUICtrlStatusBarSetBKColor($StatusBar1, 0x90EE90)
    GUICtrlSetFont($StatusBar1, 10, Default,2)
    _GUICtrlStatusBarSetText($StatusBar1, $currPosIndex+1, 0)
    _GUICtrlStatusBarSetText($StatusBar1, $info, 1)
    ToolTip("(" & $currPosIndex+1 & ".) " & $info)
    Sleep(GUICtrlRead($iTipTime)*1000)
    ToolTip("")
    EndFunc

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

    Func bEndeClick()
    Exit
    EndFunc

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

    Func bPathClick()
    $Pfad = FileSelectFolder("Bitten den Pfad auswählen","",6)
    If StringRight($Pfad, 1) <> "\" Then $Pfad = $Pfad & "\"
    GUICtrlSetData($iPath,$Pfad)
    If GUICtrlRead($iPath) = "\" Then
    GUICtrlSetData($iPath,"")
    $Pfad = ""
    EndIf
    EndFunc

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

    Func bPrintClick()
    If GUICtrlRead($Checkbox3) = 1 Then
    _FilePrintCom($ListPfad & $ListFile) ; Ausgabe auf Standard-Drucker
    Else
    _FilePrintCom($ListPfad & $ListFileShortPrint)
    EndIf
    EndFunc

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

    Func bClipboardClick()
    ClipPut($PfadExec)
    GUISetState(@SW_HIDE, $RightMenu)
    EndFunc

    Func bEscR_MenuClick()
    GUISetState(@SW_HIDE, $RightMenu)
    EndFunc

    Func bShellExClick()
    GUISetState(@SW_HIDE, $RightMenu)
    ShellExecute($PfadExec)
    EndFunc

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

    Func _WriteAllFiles()
    If FileExists($ListPfad & "\" & $ListFile) Then _
    FileMove($ListPfad & "\" & $ListFile, $ListPfad & "\" & "Rekursiv_List.bak", 1)
    If FileExists($ListPfad & "\" & $ListFileShort) Then _
    FileMove($ListPfad & "\" & $ListFileShort, $ListPfad & "\" & "Rekursiv_List_Short.bak", 1)
    If FileExists($ListPfad & "\" & $ListFileShortPrint) Then _
    FileMove($ListPfad & "\" & $ListFileShortPrint, $ListPfad & "\" & "Rekursiv_Short_P.bak", 1)
    If $Extension = "n" Then
    $Daten = _GetFileList($Pfad,$Extension,1) ; alle Ordner
    Else
    If Not StringInStr($Extension, "*") Then
    $Daten = _GetFileList($Pfad,"*." & $Extension) ; Dateien mit gewählter Erweiterung
    Else
    $Daten = _GetFileList($Pfad,"*.*") ; alle Dateien
    EndIf
    EndIf
    If Not IsArray($Daten) Or $Daten[0] = 0 Then
    GUICtrlSetData($List1, "Keine Dateien/Ordner gemäß Suchmuster vorhanden.")
    Return 0
    EndIf
    $file = FileOpen($ListPfad & $ListFile, 1)
    $fileShort = FileOpen($ListPfad & $ListFileShort, 1)
    $fileShortPrint = FileOpen($ListPfad & $ListFileShortPrint, 1)
    For $i = 1 To $Daten[0]
    FileWriteLine($file, $Daten[$i])
    $var = StringSplit($Daten[$i], "\")
    FileWriteLine($fileShort, $var[0] & "|" & $var[$var[0]]) ; Anz. Elemente & letztes Element
    FileWriteLine($fileShortPrint, $var[$var[0]])
    Next
    FileClose($file)
    FileClose($fileShort)
    FileClose($fileShortPrint)
    EndFunc

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

    Func _DisplayListLong()
    GUICtrlSetData($List1, "")
    _FileReadToArray($ListPfad & $ListFile, $arDisp)
    $anzahl = $arDisp[0]-1
    $v = 15 ; Verzögerungszeit für Progressbar (1,5 sec gesamt)
    $progress_step = (100 / $anzahl)
    If $anzahl < 100 Then $v = 1000 / $anzahl
    GUICtrlSetState($progressbar1, $GUI_SHOW)
    For $i = 1 To $arDisp[0]-1
    GUICtrlSetData($List1, $arDisp[$i])
    $tmp = Floor($progress_val)
    $progress_val = $progress_val + $progress_step
    If Floor($progress_val) > $tmp Then
    GUICtrlSetData ($progressbar1,Floor($progress_val))
    Sleep($v) ; dadurch kein Springen der Progressbar
    EndIf
    Next
    _GUICtrlListSetTopIndex($List1, 0)
    GUICtrlSetData ($progressbar1, 100)
    Sleep(1200)
    GUICtrlSetData ($progressbar1, 0)
    GUICtrlSetState($progressbar1, $GUI_HIDE)
    EndFunc

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

    Func _DisplayListShort()
    GUICtrlSetData($List1, "")
    _FileReadToArray($ListPfad & $ListFileShort, $arDisp)
    $anzahl = $arDisp[0]-1
    $v = 15 ; Verzögerungszeit für Progressbar (1,5 sec gesamt)
    $progress_step = (100 / $anzahl)
    If $anzahl < 100 Then $v = 1000 / $anzahl
    GUICtrlSetState($progressbar1, $GUI_SHOW)
    For $i = 1 To $arDisp[0]-1
    $var = StringSplit($arDisp[$i], "|")
    $point = ""
    If $var[1] > 1 Then
    For $j = 1 To $var[1]-1
    $point = $point & ". "
    Next
    EndIf
    GUICtrlSetData($List1, $point & $var[2])
    $tmp = Floor($progress_val)
    $progress_val = $progress_val + $progress_step
    If Floor($progress_val) > $tmp Then
    GUICtrlSetData ($progressbar1,Floor($progress_val))
    Sleep($v) ; dadurch kein Springen der Progressbar
    EndIf
    Next
    _GUICtrlListSetTopIndex($List1, 0)
    GUICtrlSetData ($progressbar1, 100)
    Sleep(1200)
    GUICtrlSetData ($progressbar1, 0)
    GUICtrlSetState($progressbar1, $GUI_HIDE)
    EndFunc

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

    ; Function: _FilePrintCom()
    ; Author: jos van der Zande
    Func _FilePrintCom($iFile)
    If Not FileExists($iFile) Then Return SetError(1,0,0)
    $objShellApp = ObjCreate("Shell.Application")
    $objShellApp.ShellExecute($iFile,0,0,"PRINT",0)
    EndFunc

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

    ; Function: _GetFileList()
    ; Author: jos van der Zande
    ; Einbindung des $DIR_ONLY-Flag von BugFix
    Func _GetFileList($T_DIR,$T_MASK,$DIR_ONLY=0)
    Dim $N_DIRNAMES[200000] ; max number of directories that can be scanned
    Local $N_DIRCOUNT = 0
    Local $N_FILE
    Local $N_SEARCH
    Local $N_TFILE
    Local $N_OFILE
    Local $T_FILENAMES
    Local $T_FILECOUNT
    Local $T_DIRCOUNT = 1
    ; check Filemask \ for empty File-Array by GetDirOnly
    If $T_MASK = "n" Then $T_MASK = "*.no"
    ; remove the end \ If specified
    If StringRight($T_DIR,1) = "\" Then $T_DIR = StringTrimRight($T_DIR,1)
    $N_DIRNAMES[$T_DIRCOUNT] = $T_DIR
    ; Exit if base dir doesn't exists
    If Not FileExists($T_DIR) Then Return 0
    ; keep on looping until all directories are scanned
    While $T_DIRCOUNT > $N_DIRCOUNT
    $N_DIRCOUNT = $N_DIRCOUNT + 1
    ; find all subdirs in this directory and save them in a array
    $N_SEARCH = FileFindFirstFile($N_DIRNAMES[$N_DIRCOUNT] & "\*.*")
    While 1
    $N_FILE = FileFindNextFile($N_SEARCH)
    If @error Then ExitLoop
    ; skip these references
    If $N_FILE = "." Or $N_FILE = ".." Then ContinueLoop
    $N_TFILE = $N_DIRNAMES[$N_DIRCOUNT] & "\" & $N_FILE
    ; if Directory than add to the list of directories to be processed
    If StringInStr(FileGetAttrib( $N_TFILE ),"D") > 0 Then
    $T_DIRCOUNT = $T_DIRCOUNT + 1
    $N_DIRNAMES[$T_DIRCOUNT] = $N_TFILE
    EndIf
    Wend
    FileClose($N_SEARCH) ; find all Files that mtach the MASK
    $N_SEARCH = FileFindFirstFile($N_DIRNAMES[$N_DIRCOUNT] & "\" & $T_MASK )
    If $N_SEARCH = -1 Then ContinueLoop
    While 1
    $N_FILE = FileFindNextFile($N_SEARCH)
    If @error Then ExitLoop
    ; skip these references
    If $N_FILE = "." Or $N_FILE = ".." Then ContinueLoop
    $N_TFILE = $N_DIRNAMES[$N_DIRCOUNT] & "\" & $N_FILE
    ; if Directory than add to the list of directories to be processed
    If StringInStr(FileGetAttrib( $N_TFILE ),"D") = 0 Then
    $T_FILENAMES = $T_FILENAMES & $N_TFILE & @CR
    $T_FILECOUNT = $T_FILECOUNT + 1
    ;MsgBox(0,'filecount ' & $T_FILECOUNT ,$N_TFILE)
    EndIf
    Wend
    FileClose($N_SEARCH)
    Wend
    If $DIR_ONLY = 0 Then
    $T_FILENAMES = StringTrimRight($T_FILENAMES,1)
    $N_OFILE = StringSplit($T_FILENAMES,@CR)
    Return( $N_OFILE )
    Else
    ReDim $N_DIRNAMES[$N_DIRCOUNT+1]
    $N_DIRNAMES[0] = $N_DIRCOUNT
    Return $N_DIRNAMES
    EndIf
    EndFunc ;==>_GetFileList

    [/autoit]

    Edit 5:
    Hab die vorigen Edits mal gefixed und alles zusammengefaßt.
    Hab doch noch etwas dran gebastelt. Jetzt hat es folgende Features:
    - Auslesen bestimmter Dateitypen
    - Auslesen aller Dateien
    - Auslesen nur Ordner
    - Standardanzeige: letztes Pfadelement (...Text.txt; ...Ordner)
    - Switchen auf komplette Pfadanzeige (und zurück)
    - ToolTip zeigt ausgewähltes Listenelement (bei Bedarf 2-zeilig)
    - Zeit für ToolTip frei wählbar
    - Kontextmenü für Listenelemente (Datei Ausführen; Pfad kopieren), wenn Datei und Langform
    - Ausdruck Liste (Kurzform oder Langform)
    - Statusbar zur Darstellung Progressbar und Co-Anzeige ToolTip

    • Offizieller Beitrag

    Hab ich grad gestern überarbeitet. Ist mir selbst etwas zu unstrukturiert gewesen und hat, wie du siehst wohl noch ein paar Bugs gehabt.
    Ich stelle gleich mal die neue Version rein. Nur noch ein Momentchen :)

    Edit:
    So, die aktuelle Version ist geladen.
    Vielleicht hat ja auch jemand 'ne Idee für die "Eieruhr" (s. Edit 3, Beitrag 1) ?

  • Hallo,
    ich arbeite schon eine ganze Weile mit AutoIt, finde aber immer noch etwas was ich nicht kenne.
    Ich habe ein wenig mit den UDF von Bugfix probiert. Aber wenn ich das Script in SciTe mit F5 ausführe dann bekomme ich diese Fehler:
    ERROR: can't open include file "C:\Programme\AutoIt310\Include\GuiList.au3"
    ERROR: SetError() [built-in] called with wrong number of args.
    ERROR: _GUICtrlListGetCaretIndex(): undefined function.
    ERROR: _GUICtrlListGetText(): undefined function.

    Was mich etwas wundert ist zum Beispiel diese Meldung:
    ERROR: SetError() [built-in] called with wrong number of args.
    Wenn ich in die Hilfe für die von mir verwendete Version 3.1.1.0 sehe dann hat SetError nur dieses SetError ( code )
    Im Script wurde aber:
    SetError(1,0,0)
    verwendet.
    Welche Version muss ich nehmen damit ich damit proberen kann?

    Viele Grüsse
    HeiWoMa