DirCopywithProgress.au3

  • Hallo,
    Ich hatte schon sehr oft nach so was gesucht und konnte einfach keines Finden...
    Deshalb hab ich mir selbst ein kleines Include zusammengebastelt.


    _DirFile_Rekursiv wurde Übernommen! [kommt nicht von mir]

    Ich hoffe ich habe das Richtige Unterforum verwendet sonst bitte einfach verschieben ;)

    LG SchrotterChwebnode

    Befehl

    _DirCopywithProgress ($DirCopywithProgress_Quelle, $DirCopywithProgress_Ziel, $DirCopywithProgress_Progressbar)
    DirCopywithProgress_Quelle = der Pfad zu dem Quellordner
    DirCopywithProgress_Ziel = der Pfad zu dem Zielordner
    $DirCopywithProgress_Progressbar = die Variable zu der Progressbar

    Funktion

    Es kopiert jede Datei einzeln von dem Quellordner in den Zielordner und Aktualisiert die Progressbar

    DirCopywithProgress.au3
    [autoit]

    #include-once
    #include <Array.au3>
    #include <File.au3>

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

    ;**********************************************************************************************************************************************************************************************
    ; Funktion _DirCopywithProgress ($DirCopywithProgress_Quelle, $DirCopywithProgress_Ziel, $DirCopywithProgress_Progressbar)
    ; Beschreibung Kopiert Dateien und Aktualisiert eine Progressbar
    ; Hersteller SchrotterChwebnode [AutoIt.de]
    ; Parameter
    ; $DirCopywithProgress_Quelle: der Pfad zu dem Quellordner
    ; $DirCopywithProgress_Ziel: der Pfad zu dem Zielordner
    ; $DirCopywithProgress_Progressbar: die Variable zu der Progressbar
    ; Rückgabewert
    ; Erfolg: Gibt ein Array mit 3 Spalten zurück (Dateipfad, Dateiname, Änderungsdatum)
    ; Erfolg: [0][0] = Anzahl [Anzahl][(0 = Dateipfad, 1 = Dateiname, 2 = Änderungsdatum)]
    ; Fehler: 0 setzt @error
    ; @error = 1: mindestens 1 Pfad existiert nicht
    ;**********************************************************************************************************************************************************************************************

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

    Func _DirCopywithProgress ($DirCopywithProgress_Quelle, $DirCopywithProgress_Ziel, $DirCopywithProgress_Progressbar)
    $DirCopywithProgress_StringRight_1 = StringRight ($DirCopywithProgress_Ziel, 1)
    If $DirCopywithProgress_StringRight_1 = "\" Then
    $DirCopywithProgress_Ziel = StringTrimRight ($DirCopywithProgress_Ziel, 1)
    EndIf
    $DirCopywithProgress_DirFileRekursiv = _DirFile_Rekursiv ($DirCopywithProgress_Quelle, 1, True, False, "*", "")
    If $DirCopywithProgress_DirFileRekursiv = 0 Then
    Else
    For $DirCopywithProgress_Anzahl_1 = 1 To $DirCopywithProgress_DirFileRekursiv[0][0] Step 1
    $DirCopywithProgress_Zielpfad = $DirCopywithProgress_Ziel
    $DirCopywithProgress_StringSplit_1 = StringSplit ($DirCopywithProgress_Quelle, "\")
    $DirCopywithProgress_StringSplit_2 = StringSplit ($DirCopywithProgress_DirFileRekursiv[$DirCopywithProgress_Anzahl_1][0], "\")
    If $DirCopywithProgress_StringSplit_1 = @error Then
    Else
    If $DirCopywithProgress_StringSplit_2 = @error Then
    Else
    For $DirCopywithProgress_Anzahl_2 = 1 To $DirCopywithProgress_StringSplit_2[0] Step 1
    If $DirCopywithProgress_StringSplit_1[$DirCopywithProgress_StringSplit_1[0]] = $DirCopywithProgress_StringSplit_2[$DirCopywithProgress_Anzahl_2] Then
    $DirCopywithProgress_Zielpfad = $DirCopywithProgress_Zielpfad & "\" & $DirCopywithProgress_StringSplit_2[$DirCopywithProgress_Anzahl_2]
    EndIf
    Next
    $DirCopywithProgress_Zielpfad = $DirCopywithProgress_Zielpfad & "\" & $DirCopywithProgress_DirFileRekursiv[$DirCopywithProgress_Anzahl_1][1]
    FileCopy ($DirCopywithProgress_DirFileRekursiv[$DirCopywithProgress_Anzahl_1][0] & $DirCopywithProgress_DirFileRekursiv[$DirCopywithProgress_Anzahl_1][1], $DirCopywithProgress_Zielpfad, 1 + 8)
    EndIf
    EndIf
    GUICtrlSetData ($DirCopywithProgress_Progressbar, 100 / $DirCopywithProgress_DirFileRekursiv[0][0] * $DirCopywithProgress_Anzahl_1)
    Next
    EndIf
    EndFunc

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

    ;______________________________________________________________________________________________________________________________________________________________________________________________
    ;______________________________________________________________________________________________________________________________________________________________________________________________
    ;______________________________________________________________________________________________________________________________________________________________________________________________
    ;______________________________________________________________________________________________________________________________________________________________________________________________
    ;**********************************************************************************************************************************************************************************************
    ; Funktion _DirFile_Rekursiv ($DirFile_Rekursiv_Pfad[, $DirFile_Rekursiv_Auslesen[, $DirFile_Rekursiv_Unterordner[, $DirFile_Rekursiv_Datum [, $DirFile_Rekursiv_Dateityp = "*"[, $DirFile_Rekursiv_Auslassen = ""]]]]])
    ; Beschreibung ermittelt alle Dateien/Ordner des angegebenen Verzeichnisses
    ; Parameter
    ; $DirFile_Rekursiv_Pfad: der zu durchsuchende Ordner (Angabe: einzelner Ordner als String oder mehrere Ordner im Array beginnend bei 1)
    ; optional $DirFile_Rekursiv_OrdnerDateien: 1 = Dateien auflisten (Standard) 2 = Ordner auflisten
    ; optional $DirFile_Rekursiv_Unterordner: True = Unterordner miteinbeziehen (Standard) False = Unterordner nicht miteinbeziehen
    ; optional $DirFile_Rekursiv_SpalteDatum: True = Änderungsdatum der Datei ermitteln False = Änderungsdatum der Datei nicht ermitteln (Standard)
    ; optional $DirFile_Rekursiv_Dateityp: einzuschließende Dateitypen (mehrere Typen durch | trennen) "*" >>> alle (Standard)
    ; optional $DirFile_Rekursiv_Auslassen: Wörter, die im Pfad oder Dateinamen vorkommen, auslassen (mehrere durch | trennen) "" <<< Standard
    ; Rückgabewert
    ; Erfolg: Gibt ein Array mit 3 Spalten zurück (Dateipfad, Dateiname, Änderungsdatum)
    ; Erfolg: [0][0] = Anzahl [Anzahl][(0 = Dateipfad, 1 = Dateiname, 2 = Änderungsdatum)]
    ; Fehler: 0 setzt @error
    ; @error = 1: mindestens 1 Pfad existiert nicht
    ;**********************************************************************************************************************************************************************************************

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

    ;********************************************
    ; Ordner rekursiv (Hauptfunktion) *
    ;********************************************

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

    Func _DirFile_Rekursiv ($DirFile_Rekursiv_Pfad, $DirFile_Rekursiv_OrdnerDateien = 1, $DirFile_Rekursiv_Unterordner = True, $DirFile_Rekursiv_SpalteDatum = False, $DirFile_Rekursiv_Dateityp = "*", $DirFile_Rekursiv_Auslassen = "")
    Local $Verzeichnis_Alle[1] ;Array für die Ordner
    Local $Array_Alle[1000000][3] ;Array für die Ordner und Dateien
    Local $szDrive, $szDir, $szFName, $szExt

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

    If Not IsArray($DirFile_Rekursiv_Pfad) Then
    $DirFile_Rekursiv_Pfad_tmp = $DirFile_Rekursiv_Pfad
    Dim $DirFile_Rekursiv_Pfad[2]
    $DirFile_Rekursiv_Pfad[1] = $DirFile_Rekursiv_Pfad_tmp
    EndIf

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

    For $i = 1 To UBound($DirFile_Rekursiv_Pfad) - 1
    If Not FileExists($DirFile_Rekursiv_Pfad[$i]) Or Not StringInStr($DirFile_Rekursiv_Pfad[$i], ":") Then
    SetError(1)
    Return 0
    EndIf

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

    If StringRight($DirFile_Rekursiv_Pfad[$i], 1) <> "\" Then $DirFile_Rekursiv_Pfad[$i] &= "\"

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

    $DirFile_Rekursiv_Pfad_einzeln = $DirFile_Rekursiv_Pfad[$i]

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

    If $DirFile_Rekursiv_Unterordner = True Then ;mit Unterordner
    _DirFile_Rekursiv_mit_unterordner($DirFile_Rekursiv_Pfad_einzeln, $Verzeichnis_Alle)
    _ArrayAdd($Verzeichnis_Alle, $DirFile_Rekursiv_Pfad_einzeln)
    Else ;ohne Unterordner
    $Verzeichnis_Alle = $DirFile_Rekursiv_Pfad
    EndIf
    Next

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

    If IsArray($Verzeichnis_Alle) Then $Verzeichnis_Alle[0] = UBound($Verzeichnis_Alle) - 1 ;In die erste Zeile die Anzahl der Dateien schreiben

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

    If $DirFile_Rekursiv_OrdnerDateien = 1 Then ;Dateien auflisten
    $zaehler_fortlaufend = 0

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

    If Not IsArray($Verzeichnis_Alle) Then
    $Verzeichnis_Alle_tmp = $Verzeichnis_Alle
    Dim $Verzeichnis_Alle[2]
    $Verzeichnis_Alle[1] = $Verzeichnis_Alle_tmp
    EndIf

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

    For $u = 1 To UBound($Verzeichnis_Alle) - 1
    $array_alle_dateien = _FileListToArray($Verzeichnis_Alle[$u], "*", 1)

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

    For $k = 1 To UBound($array_alle_dateien) - 1
    $kriterien_ok = 0

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

    If $DirFile_Rekursiv_Dateityp = "*" Then ;Dateityp nicht angegeben oder alle Dateien
    $kriterien_ok = 1

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

    ElseIf StringInStr($DirFile_Rekursiv_Dateityp, "|") Then ;Dateitypen angegeben
    $dateityp_split = StringSplit($DirFile_Rekursiv_Dateityp, "|")
    $DirFile_Rekursiv_dateiendung_array = _PathSplit($array_alle_dateien[$k], $szDrive, $szDir, $szFName, $szExt)
    $DirFile_Rekursiv_dateiendung = $DirFile_Rekursiv_dateiendung_array[4]
    For $i = 1 To UBound($dateityp_split) - 1
    If "." & $dateityp_split[$i] = StringRight($array_alle_dateien[$k], StringLen($DirFile_Rekursiv_dateiendung)) Then
    $kriterien_ok = 1
    ExitLoop
    EndIf
    Next
    EndIf

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

    If $DirFile_Rekursiv_Auslassen <> "" Then ;Wörter in dem Pfad und Datei auslassen
    $auslassen_split = StringSplit($DirFile_Rekursiv_Auslassen, "|")
    For $i = 1 To UBound($auslassen_split) - 1
    If StringInStr($array_alle_dateien[$k], $auslassen_split[$i]) Or StringInStr($Verzeichnis_Alle[$u], $auslassen_split[$i]) Then
    $kriterien_ok = 0
    ExitLoop
    EndIf
    Next
    EndIf

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

    ;Papierkorb und System Volume Information wird nicht mitkopiert
    If StringInStr($array_alle_dateien[$k], 'RECYCLER') Or StringInStr($Verzeichnis_Alle[$u], 'RECYCLER') _
    Or StringInStr($array_alle_dateien[$k], 'RECYCLED') Or StringInStr($Verzeichnis_Alle[$u], 'RECYCLED') _
    Or StringInStr($array_alle_dateien[$k], 'System Volume Information') Or StringInStr($Verzeichnis_Alle[$u], 'System Volume Information') _
    Or StringInStr($array_alle_dateien[$k], '$RECYCLE.BIN') Or StringInStr($Verzeichnis_Alle[$u], '$RECYCLE.BIN') Then
    $kriterien_ok = 0
    ExitLoop
    EndIf

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

    ;wenn der Dateityp passt und die Datei bzw. der Ordner nicht ausgelassen werden soll
    If $kriterien_ok = 1 Then
    $zaehler_fortlaufend += 1
    $Array_Alle[$zaehler_fortlaufend][0] = $Verzeichnis_Alle[$u]
    $Array_Alle[$zaehler_fortlaufend][1] = $array_alle_dateien[$k]

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

    If $DirFile_Rekursiv_SpalteDatum = True Then
    $time2 = FileGetTime($Verzeichnis_Alle[$u] & "\" & $array_alle_dateien[$k], 0) ;"Datum geändert" auslesen
    $Array_Alle[$zaehler_fortlaufend][2] = $time2[0] & $time2[1] & $time2[2] & $time2[3] & $time2[4] & $time2[5]
    EndIf

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

    EndIf

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

    Next
    Next

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

    Else ;Ordner auflisten
    For $i = 1 To UBound($Verzeichnis_Alle) - 1
    $Array_Alle[$i][0] = $Verzeichnis_Alle[$i]
    $zaehler_fortlaufend = UBound($Verzeichnis_Alle) - 1
    Next
    EndIf

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

    ;Leere Zeilen am Ende löschen
    ReDim $Array_Alle[$zaehler_fortlaufend + 1][3]

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

    ;In die erste Zeile die Anzahl der Dateien schreiben
    If IsArray($Array_Alle) Then $Array_Alle[0][0] = UBound($Array_Alle) - 1

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

    $Verzeichnis_Alle = 0

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

    Return $Array_Alle
    EndFunc ;==>_DirFile_Rekursiv

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

    ;**************************************
    ; Unterordner durchsuchen *
    ;**************************************

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

    Func _DirFile_Rekursiv_mit_unterordner ($DirFile_Rekursiv_Pfad, ByRef $Verzeichnis_Alle)
    $verzeichnisse = _FileListToArray ($DirFile_Rekursiv_Pfad, "*", 2)

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

    For $i = 1 To UBound ($verzeichnisse) - 1
    $verzeichnisse[$i] = $DirFile_Rekursiv_Pfad & $verzeichnisse[$i] & "\"
    _ArrayAdd ($Verzeichnis_Alle, $verzeichnisse[$i])
    _DirFile_Rekursiv_mit_unterordner ($verzeichnisse[$i], $Verzeichnis_Alle)
    Next
    EndFunc ;==>_DirFile_Rekursiv_mit_unterordner

    [/autoit]
    Example.au3
    [autoit]

    #include <DirCopywithProgress.au3>

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

    $GUI = GUICreate ("DirCopywithProgress", 500, 40, -1, -1)
    $GUIProgress = GUICtrlCreateProgress (0, 0, 500, 40)
    GUISetState (@SW_SHOW, $GUI)

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

    _DirCopywithProgress (@MyDocumentsDir, @DesktopDir & "\Example DirCopywithProgress", $GUIProgress)

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

    MsgBox (0, "Abgeschlossen", "Kopieren wurde Fertiggestellt")
    ShellExecute (@DesktopDir & "\Example DirCopywithProgress")

    [/autoit]
    • Offizieller Beitrag

    Mal ein paar Hinweise:
    - Variablennamen sollten zwar aussagekräftig - aber auch lesbar sein. Den Funktionsnamen als Bestandteil der Variblennamen zu verwenden ist hier kontraproduktiv. Kurz und prägnant, gern auch mit Notationskürzel vorweg in der Form: "$sQuelle, $sZiel, $iIDProgress".
    - Du berechnest in deiner Schleife in jedem Durchlauf aufs neue die Schrittweite zum Setzen der Progressbar. Das ist zwar unproblematisch für das Zeitverhalten (da ja sowieso eine Berechnung stattfindet) aber ich persönlich finde es besser lesbar, wenn die Schrittweite extra definiert wird. Statt

    [autoit]

    GUICtrlSetData ($DirCopywithProgress_Progressbar, 100 / $DirCopywithProgress_DirFileRekursiv[0][0] * $DirCopywithProgress_Anzahl_1)

    [/autoit]

    besser

    [autoit]

    ; vor der Schleife
    $iStep = 100 / $DirCopywithProgress_DirFileRekursiv[0][0]
    ; in der Schleife
    GUICtrlSetData ($DirCopywithProgress_Progressbar, $iStep * $DirCopywithProgress_Anzahl_1)

    [/autoit]


    - Verwende NIE _ArrayAdd in einer Funktion, die durchaus tausende male diese Funktion aufrufen kann. Denn das ist eine totale Performancebremse. Besser: Array vordefinieren in vorhersehbaren Größenordnungen ( z.B. 100 ) und einen Zähler extra führen. Wenn der Zähler die Vorgabegröße erreicht hat, erst dann das Array um den gleichen Wert vergrößern. Am Ende dann mit ReDim und dem Zählerwert auf die tatsächliche Inhaltsgröße stutzen.

    Das waren jetzt Dinge, die mir beim Drüberschauen ins Auge gesprungen sind. Inhaltlich/funktionell habe ich es nicht geprüft.

  • Hi,

    wegen den Variablen ich bin es gewohnt so da ich so auch das von mir schnell finde was ich suche :P.
    Das mit _ArrayAdd das habe ich übernommen das kommt nicht von mir :) habe ich auch geschrieben beim ersten Beitrag.
    Aber trotzdem danke für den Tipp falls ich das mal brauche werde ich es mir merken :)

    LG Christian