Hi Leute,
ich habe vor kurzem eine UDF geschrieben, mit der man einen Ordner mit Unterordner in einen anderen kopieren kann, welches aber vorher die MD5 Checksums checkt und wenn sie gleich sind die Datei überspringt, wenn sie aber verschieden sind die Original Datei in einem externen Ordner "backupt" und dann überschreibt.
Mein Script hat keinen Syntaxfehler, aber es werden anscheinend Dateien übersprungen.
Ich habe den Script schon mehrmals durchgesehen, habe aber keine Ahnung woran es liegen könnte.
Ich benutze zum Ordnerauflisten die UDF von AutoIt.de User Tweaky, ich habe sie mit Region Tags markiert.
Vieleicht findet ihr den Fehler, ich habe es auch schon mit Debug versucht und schon DebugConsoleWrite's erstellt um Tweakys UDF zu testen, mir ist aber nichts aufgefallen
Bei einem Versuch hat das Script erst ewig gerödelt, aber am Ende hat er gar nichts kopiert, geschweige denn Backups erstellt.
Mfg Fliwatt
Spoiler anzeigen
#region Rekursive Ordnerauflistung Funktion
#include <Array.au3>
#include <File.au3>
#include <Crypt.au3>
;*******************************************************************************************************************************************************************************************************************************************
; Funktion _ordner_rekursiv($udf_quellordner[, $udf_Ordner_Dateien[, $udf_unterordner=True[, $udf_spalte_datum=False[, $udf_dateityp = "*"[, $udf_auslassen = ""]]]]])
; Beschreibung ermittelt alle Dateien/Ordner des angegebenen Verzeichnisses
; Parameter $udf_quellordner: der zu durchsuchende Ordner (Angabe: einzelner Ordner als String oder mehrere Ordner im Array beginnend bei 1)
; optional $udf_Ordner_Dateien: 1 = Dateien auflisten (Standard) 2 = Ordner auflisten
; optional $udf_unterordner: True = Unterordner miteinbeziehen (Standard) False = Unterordner nicht miteinbeziehen
; optional $udf_spalte_datum: True = Änderungsdatum der Datei ermitteln False = Änderungsdatum der Datei nicht ermitteln (Standard)
; optional $udf_dateityp: einzuschließende Dateitypen (mehrere Typen durch | trennen) "*" >>> alle (Standard)
; optional $udf_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 (Dateiname, Dateipfad, Änderungsdatum)
; Fehler: 0 setzt @error
; @error = 1 mindestens 1 Pfad existiert nicht
; Autor Tweaky (http://www.autoit.de)
;*******************************************************************************************************************************************************************************************************************************************
;********************************************
; Ordner rekursiv (Hauptfunktion) *
;********************************************
Func _ordner_rekursiv($udf_quellordner, $udf_Ordner_Dateien = 1, $udf_unterordner = True, $udf_spalte_datum = False, $udf_dateityp = "*", $udf_auslassen = "")
Local $verzeichnisse_alle[1] ;Array für die Ordner
Local $array_alles[1000000][3] ;Array für die Ordner und Dateien
Local $szDrive, $szDir, $szFName, $szExt
If Not IsArray($udf_quellordner) Then ;Falls der Quellordner kein Array ist, ein Array erstellen
$udf_quellordner_tmp = $udf_quellordner
Dim $udf_quellordner[2]
$udf_quellordner[0] = 1
$udf_quellordner[1] = $udf_quellordner_tmp
EndIf
For $i = 1 To UBound($udf_quellordner) - 1
If Not FileExists($udf_quellordner[$i]) Or Not StringInStr($udf_quellordner[$i], ":") Then
SetError(1) ;mindestens 1 Pfad existiert nicht
Return 0
EndIf
If StringRight($udf_quellordner[$i], 1) <> "\" Then $udf_quellordner[$i] &= "\"
[/autoit] [autoit][/autoit] [autoit]$udf_quellordner_einzeln = $udf_quellordner[$i]
[/autoit] [autoit][/autoit] [autoit]If $udf_unterordner = True Then ;mit Unterordner
_ordner_rekursiv_mit_unterordner($udf_quellordner_einzeln, $verzeichnisse_alle)
_ArrayAdd($verzeichnisse_alle, $udf_quellordner_einzeln)
Else ;ohne Unterordner
$verzeichnisse_alle = $udf_quellordner
EndIf
Next
If IsArray($verzeichnisse_alle) Then $verzeichnisse_alle[0] = UBound($verzeichnisse_alle) - 1 ;In die erste Zeile die Anzahl der Dateien schreiben
[/autoit] [autoit][/autoit] [autoit]$zaehler_fortlaufend = 0
[/autoit] [autoit][/autoit] [autoit]If $udf_Ordner_Dateien = 1 Then ;Dateien auflisten
[/autoit] [autoit][/autoit] [autoit]If Not IsArray($verzeichnisse_alle) Then
$verzeichnisse_alle_tmp = $verzeichnisse_alle
Local $verzeichnisse_alle[2] ;Array für die Ordner
$verzeichnisse_alle[1] = $verzeichnisse_alle_tmp
EndIf
For $u = 1 To UBound($verzeichnisse_alle) - 1
$array_alle_dateien = _FileListToArray($verzeichnisse_alle[$u], "*", 1)
For $k = 1 To UBound($array_alle_dateien) - 1
$kriterien_ok = 0
If $udf_dateityp = "*" Then ;Dateityp nicht angegeben oder alle Dateien
$kriterien_ok = 1
Else ;1 oder mehrere Dateitypen angegeben
$dateityp_split = StringSplit($udf_dateityp, "|")
$udf_dateiendung_array = _PathSplit($array_alle_dateien[$k], $szDrive, $szDir, $szFName, $szExt)
$udf_dateiendung = $udf_dateiendung_array[4]
For $i = 1 To UBound($dateityp_split) - 1
If "." & $dateityp_split[$i] = StringRight($array_alle_dateien[$k], StringLen($udf_dateiendung)) Then
$kriterien_ok = 1
ExitLoop
EndIf
Next
EndIf
If $udf_auslassen <> "" Then ;Wörter in dem Pfad und Datei auslassen
$auslassen_split = StringSplit($udf_auslassen, "|")
For $i = 1 To UBound($auslassen_split) - 1
If StringInStr($array_alle_dateien[$k], $auslassen_split[$i]) Or StringInStr($verzeichnisse_alle[$u], $auslassen_split[$i]) Then
$kriterien_ok = 0
ExitLoop
EndIf
Next
EndIf
;Papierkorb und System Volume Information wird nicht aufgelistet
If StringInStr($array_alle_dateien[$k], 'RECYCLER') Or StringInStr($verzeichnisse_alle[$u], 'RECYCLER') _
Or StringInStr($array_alle_dateien[$k], 'RECYCLED') Or StringInStr($verzeichnisse_alle[$u], 'RECYCLED') _
Or StringInStr($array_alle_dateien[$k], 'System Volume Information') Or StringInStr($verzeichnisse_alle[$u], 'System Volume Information') _
Or StringInStr($array_alle_dateien[$k], '$RECYCLE.BIN') Or StringInStr($verzeichnisse_alle[$u], '$RECYCLE.BIN') Then
$kriterien_ok = 0
ExitLoop
EndIf
;wenn der Dateityp passt und die Datei bzw. der Ordner nicht ausgelassen werden soll
If $kriterien_ok = 1 Then
$zaehler_fortlaufend += 1
$array_alles[$zaehler_fortlaufend][0] = $verzeichnisse_alle[$u]
$array_alles[$zaehler_fortlaufend][1] = $array_alle_dateien[$k]
If $udf_spalte_datum = True Then $array_alles[$zaehler_fortlaufend][2] = FileGetTime($verzeichnisse_alle[$u] & $array_alle_dateien[$k], 0, 1)
EndIf
Next
Next
Else ;Ordner auflisten
For $i = 1 To UBound($verzeichnisse_alle) - 1
$kriterien_ok = 1
;Papierkorb und System Volume Information wird nicht aufgelistet
If StringInStr($verzeichnisse_alle[$i], 'RECYCLER') Or StringInStr($verzeichnisse_alle[$i], 'RECYCLED') _
Or StringInStr($verzeichnisse_alle[$i], 'System Volume Information') Or StringInStr($verzeichnisse_alle[$i], '$RECYCLE.BIN') Then
$kriterien_ok = 0
ExitLoop
EndIf
If $kriterien_ok = 1 Then
$zaehler_fortlaufend += 1
$array_alles[$zaehler_fortlaufend][0] = $verzeichnisse_alle[$i]
EndIf
Next
EndIf
;Leere Zeilen am Ende löschen
ReDim $array_alles[$zaehler_fortlaufend + 1][3]
;In die erste Zeile die Anzahl der Dateien schreiben
If IsArray($array_alles) Then $array_alles[0][0] = UBound($array_alles) - 1
$verzeichnisse_alle = 0 ;Array löschen
[/autoit] [autoit][/autoit] [autoit]Return $array_alles ;Array zurückgeben
EndFunc ;==>_ordner_rekursiv
;**************************************
; Unterordner durchsuchen *
;**************************************
Func _ordner_rekursiv_mit_unterordner($udf_quellordner, ByRef $verzeichnisse_alle)
$verzeichnisse = _FileListToArray($udf_quellordner, "*", 2)
For $i = 1 To UBound($verzeichnisse) - 1
$verzeichnisse[$i] = $udf_quellordner & $verzeichnisse[$i] & "\"
_ArrayAdd($verzeichnisse_alle, $verzeichnisse[$i])
_ordner_rekursiv_mit_unterordner($verzeichnisse[$i], $verzeichnisse_alle)
Next
EndFunc ;==>_ordner_rekursiv_mit_unterordner
#endregion Rekursive Ordnerauflistung Funktion
Func _DirCopyBackup($sSource,$sTarget,$sBackupFolder)
_Crypt_Startup()
Local $iCounterDirCopyBackup = 1
Local $iCounterDirCopyBackup2 = 1
Local $fFound = 0
Local $aSourceRekursiv = _ordner_rekursiv($sSource)
Local $aTargetRekursiv = _ordner_rekursiv($sTarget)
For $iCounterDirCopyBackup = 1 To Ubound($aSourceRekursiv)-1
For $iCounterDirCopyBackup2 = 1 To Ubound($aTargetRekursiv)-1
If StringTrimLeft($aSourceRekursiv[$iCounterDirCopyBackup][0] & $aSourceRekursiv[$iCounterDirCopyBackup][1],StringLen($sSource)) = StringTrimLeft($aTargetRekursiv[$iCounterDirCopyBackup2][0] & $aTargetRekursiv[$iCounterDirCopyBackup2][1],StringLen($sTarget)) Then
If Not _Crypt_HashFile($aSourceRekursiv[$iCounterDirCopyBackup][0] & $aSourceRekursiv[$iCounterDirCopyBackup][1],$CALG_MD5) = _Crypt_HashFile($aTargetRekursiv[$iCounterDirCopyBackup2][0] & $aTargetRekursiv[$iCounterDirCopyBackup2][1], $CALG_MD5) Then
FileCopy($aSourceRekursiv[$iCounterDirCopyBackup][0] & $aSourceRekursiv[$iCounterDirCopyBackup][1],$sBackupFolder & StringTrimLeft($aTargetRekursiv[$iCounterDirCopyBackup2][0] & $aTargetRekursiv[$iCounterDirCopyBackup2][1],StringLen($sTarget)),9)
FileCopy($aSourceRekursiv[$iCounterDirCopyBackup][0] & $aSourceRekursiv[$iCounterDirCopyBackup][1],$aTargetRekursiv[$iCounterDirCopyBackup2][0] & $aTargetRekursiv[$iCounterDirCopyBackup2][1],1)
$fFound = 1
Else
$fFound = 1
EndIf
Endif
Next
If $fFound = 0 Then
FileCopy($aSourceRekursiv[$iCounterDirCopyBackup][0] & $aSourceRekursiv[$iCounterDirCopyBackup][1],$sTarget & StringTrimLeft($aSourceRekursiv[$iCounterDirCopyBackup][0] & $aSourceRekursiv[$iCounterDirCopyBackup][1],StringLen($sSource)),9)
Else
Local $fFound = 0
EndIf
Next
Return $aSourceRekursiv[0][0]
_Crypt_Shutdown()
EndFunc
MsgBox(0,"",_DirCopyBackup(FileSelectFolder("Source",""),FileSelectFolder("Target",""),FileSelectFolder("Backup",""))) ;Nur zum Test der meines Scriptes, nicht notwendig zum Ausführen.
Exit
PS _DirCopyBackup(ab z.163) ist meine Funktion, der Rest ist von Tweaky