Problem mit _MultiFileCopy

  • okay, recht haste natürlich xD

    Wenn ich dieses Script hier richtig verstehe, dann Kopiert es NUR die Dateien, die in der "!copydata.mfc" gelistet sind?
    Wenn dem so ist, könnte man dann die Funktion, die dafür sorgt, das die Files in die Liste geschrieben werden, so umschreiben,
    dass nur die Einträge von den Files in diese Liste eingetragen werden, die nicht älter sind als ein benutzerdefiniertes Datum?

    Ich hab schon einige Varianten durchprobiert, wie ich es am besten hinbekomme, aber es kommt immer wieder der gleiche Fehler.
    Hier mal der Code:

    Spoiler anzeigen
    [autoit]

    If IsArray($aSource) Then
    If Not IsNumber($aSource[0]) Then Return SetError(1, 0, 0)
    For $i = 1 To $aSource[0]
    $aMFC[7] += FileGetSize($aSource[$i])
    Next
    Else
    $sSourcePath = $aSource
    If StringRight($sSourcePath, 1) <> '\' Then $sSourcePath &= '\'
    $strSize = 0
    ToolTip('Bitte warten! Verzeichnis wird eingelesen!', @DesktopWidth / 2 - 100, 10)
    If FileExists($sSourcePath & '!copydata.mfc') And $sDestPath <> '' Then
    Local $sFile = StringTrimRight(FileRead($sSourcePath & '!copydata.mfc'), 2)
    $strSize = StringLeft($sFile, StringInStr($sFile, @CRLF) - 1)
    $aSource = StringSplit(StringTrimLeft($sFile, StringInStr($sFile, @CRLF) + 1), @CRLF, 1)
    Else
    If FileExists($sSourcePath & '!copydata.mfc') Then FileDelete($sSourcePath & '!copydata.mfc')
    $aSource = _GetFilesFolder_Rekursiv($sSourcePath)
    Local $hFile = FileOpen($sSourcePath & '!copydata.mfc', 2)
    If $hFile <> -1 Then
    FileWriteLine($hFile, $strSize)
    For $i = 1 To $aSource[0]
    $filetime = FileGetTime($aSource[$i])
    If Not ($inputtime - ($filetime[0] & $filetime[1] & $filetime[2])) > 2 Then FileWriteLine($hFile, $aSource[$i])
    Next
    FileClose($hFile)
    EndIf
    EndIf
    $aMFC[7] = $strSize
    ToolTip('')
    If $sDestPath = '' Then Return SetError(0, 0, 1)
    EndIf

    [/autoit]

    Das ist das Script vom 1. Beitrag dieses Topics, Auszug von Zeile 56 bis Zeile 85.
    hinzugefügt hab ich folgende Zeilen:

    [autoit]

    $filetime = FileGetTime($aSource[$i]) ; von mir hinzugefügt
    If Not ($inputtime - ($filetime[0] & $filetime[1] & $filetime[2])) > 2 Then FileWriteLine($hFile, $aSource[$i]); die auch

    [/autoit]


    Die Variable $inputdate wird "Global" zu beginn des Scripts per Inputbox aufgerufen, dort trage ich ein Referenzdatum ein.
    Und von allen Dateien in den Ordnern, die durchforstet werden, die nicht älter sind als 2 Tage, vom Referentdatum gesehen,
    sollen kopiert werden.

    Wenn ich das Script debugge wird mir weder Warnung noch Fehler angezeigt, doch führe ich das Script aus, erhalte ich immer
    diese Fehlermeldung:

    [autoit]


    >"C:\Program Files (x86)\AutoIt3\SciTE\..\autoit3.exe" /ErrorStdOut "C:\Users\Lottich\Desktop\AutoIt v3 Script (neu).au3"
    C:\Users\Lottich\Desktop\AutoIt v3 Script (neu).au3 (89) : ==> Subscript used with non-Array variable.:
    If Not ($inputtime - ($filetime[0] & $filetime[1] & $filetime[2])) > 2 Then FileWriteLine($hFile, $aSource[$i])
    If Not ($inputtime - ($filetime^ ERROR
    >Exit code: 1 Time: 7.613

    [/autoit]

    Ich komm hier einfach nicht mehr weiter, wie krieg ich diesen Fehler weg??

    mfG Lottich

    • Offizieller Beitrag

    Dein Fehler rührt von der Zeile

    [autoit]

    $filetime = FileGetTime($aSource[$i]) ; von mir hinzugefügt

    [/autoit]


    her.
    Wenn FileGetTime fehlschlägt, dann wird kein Array zurückgegeben und folglich ist die dauffolgende Zeile
    nicht auzuführen. Du solltestet abfragen ob die Abfrage erfolgreich war, z.B. so:

    [autoit]

    $filetime = FileGetTime($aSource[$i]) ; von mir hinzugefügt
    If Not @Error then
    If Not ($inputtime - ($filetime[0] & $filetime[1] & $filetime[2])) > 2 Then FileWriteLine($hFile, $aSource[$i]); die auch
    EndIf

    [/autoit]


    Anstatt auf @Error abzufragen könnte man auch überprüfen ob die Rückgabe ein Array ist:

    [autoit]

    $filetime = FileGetTime($aSource[$i]) ; von mir hinzugefügt
    If IsArray($filetime) then
    If Not ($inputtime - ($filetime[0] & $filetime[1] & $filetime[2])) > 2 Then FileWriteLine($hFile, $aSource[$i]); die auch
    EndIf

    [/autoit]


    Hab das ganze jetzt nicht getestet, weil ich nicht deinen ganzen Code habe.
    Deine Berechnungformel sieht ein wenig konfus aus und ergibt für mich keinen Sinn.

  • Vielleicht denk ich da einfach viel zu quer mit der Berechnung, scheint auch falsch zu sein, denn es werden keine Einträge in die "!copydata.mfc" geschrieben. Der Plan ist, wie gesagt , dass nur Dateien dort rein geschrieben werden, die nicht älter als 2 Tage sind.

    Ich hab jetzt "@error" in meinen Zeilen eingebaut und der Fehler kommt nun Tatsächlich nicht mehr. Danke Dafür.
    Es stellte sich nun aber heraus, dass meine Rechnung voll fürn Allerwertesten war, die musste ich anpassen.
    Jetzt funktioniert es.

    Spoiler anzeigen
    [autoit]

    ;===werden benötigt=============================================================
    #include
    #include

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

    Global $inputtime = InputBox("Datum des Updates", "Trage hier das Referenzdatum ein." & @LF & @LF & "!!!! Wichtig: !!!!" & @LF & @LF & "nur die Zahlen im Format: JJJJMMTT" & @LF & "Beispiel 8.März 2007 ---> 20070308", @YEAR & @MON & @MDAY)

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

    Global $strFiles = '', $strSize = 0
    ;===============================================================================

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

    ;===Beispiel 1 (erstellen der Datei "!copydata.mfc" im Quellverzeichnis)========
    Global $sSourcePath = ''

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

    Global $aReturn = _MultiFileCopy($sSourcePath)

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

    MsgBox(0, 'MFC', '"!copydata.mfc" wurde erstellt!')
    ;===============================================================================

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

    ;===Beispiel 2 (komplettes Verzeichnis kopieren)================================
    ; Alle Dateien und Unterverzeichnisse (rekursiv) werden kopiert
    ; Verzeichnisstruktur der Quelle wird übernommen
    Global $sSourcePath = ''
    Global $sDestinationPath = ''; Zielpfad (wird ggf. erstellt)

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

    Global $aReturn = _MultiFileCopy($sSourcePath, $sDestinationPath, False)
    ;===============================================================================

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

    ;===Beispiel 3 (mehrere Dateien kopieren)=======================================
    ; Alle Dateien aus dem Array werden ins Zielverzeichnis kopiert
    ; Array[0] muss die Anzahl der zu kopierenden Dateien enthalten
    ;~ Global $aSource[4] = [3, @SystemDir & '\shell32.dll', @SystemDir & '\mspaint.exe', @SystemDir & '\eula.txt']
    ;~ Global $sDestinationPath = @ScriptDir & '\Tmp2'; Zielpfad (wird ggf. erstellt)

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

    ;~ Global $aReturn = _MultiFileCopy($aSource, $sDestinationPath, False)
    ;===============================================================================

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

    ;===============================================================================
    ; Function Name: _MultiFileCopy
    ; Description:: Kopiert mehrere Dateien mit Progressbar
    ; Parameter(s): Array mit Dateien zum kopieren oder Quellpfad,
    ; Zielpfad,
    ; überschreiben? [True/False],
    ; Wenn überschreiben = True, dann PreFix zum überschreiben
    ; Return Value(s): Array mit den kopierten Dateien
    ; Requirement(s): Global $strFiles = '', $strSize = 0
    ; #include
    ; #include
    ; Author(s): Tom99, progandy, eukalyptus and Oscar (http://www.autoit.de)
    ;===============================================================================
    Func _MultiFileCopy($aSource, $sDestPath = '', $bOverWrite = True, $sPreFix = '!Copy')
    Local $oldGUICloseOnESC = Opt('GUICloseOnESC', 0)
    Local $ret, $sShowSource, $sShowDest, $sSourcePath = '', $sNewFolder = '', $k
    Local $filetime, $filetimeist, $timedifferenz
    Local $aMFC[12] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, False, DllOpen('user32.dll')]
    If IsArray($aSource) Then
    If Not IsNumber($aSource[0]) Then Return SetError(1, 0, 0)
    For $i = 1 To $aSource[0]
    $aMFC[7] += FileGetSize($aSource[$i])
    Next
    Else
    $sSourcePath = $aSource
    If StringRight($sSourcePath, 1) <> '\' Then $sSourcePath &= '\'
    $strSize = 0
    ToolTip('Bitte warten! Verzeichnis wird eingelesen!', @DesktopWidth / 2 - 100, 10)
    If FileExists($sSourcePath & '!copydata.mfc') And $sDestPath <> '' Then
    Local $sFile = StringTrimRight(FileRead($sSourcePath & '!copydata.mfc'), 2)
    $strSize = StringLeft($sFile, StringInStr($sFile, @CRLF) - 1)
    $aSource = StringSplit(StringTrimLeft($sFile, StringInStr($sFile, @CRLF) + 1), @CRLF, 1)
    Else
    If FileExists($sSourcePath & '!copydata.mfc') Then FileDelete($sSourcePath & '!copydata.mfc')
    $aSource = _GetFilesFolder_Rekursiv($sSourcePath)
    Local $hFile = FileOpen($sSourcePath & '!copydata.mfc', 2)
    If $hFile <> -1 Then
    FileWriteLine($hFile, $strSize)
    For $i = 1 To $aSource[0]
    $filetime = FileGetTime($aSource[$i]) ; von mir hinzugefügt
    If Not @error then
    If $inputtime = ($filetime[0] & $filetime[1] & $filetime[2]) Then
    FileWriteLine($hFile, $aSource[$i]); die auch
    Endif
    EndIf
    Next
    FileClose($hFile)
    EndIf
    EndIf
    $aMFC[7] = $strSize
    ToolTip('')
    If $sDestPath = '' Then Return SetError(0, 0, 1)
    EndIf
    If StringRight($sDestPath, 1) <> '\' Then $sDestPath &= '\'
    If Not FileExists($sDestPath) Then
    If Not DirCreate($sDestPath) Then Return SetError(2, 0, 0)
    EndIf
    $sShowDest = StringRegExpReplace($sDestPath, '(.{15})(.*)(.{35})', '$1' & '[...]' & '$3')
    Local $aReturn = $aSource
    Local $callback = DllCallbackRegister('__Progress', 'int', 'uint64;uint64;uint64;uint64;dword;dword;ptr;ptr;str')
    Local $ptr = DllCallbackGetPtr($callback)
    Local $DllKernel32 = DllOpen('kernel32.dll')
    __ProgressCreate($aMFC)
    $aMFC[9] = TimerInit()
    For $i = 1 To $aSource[0]
    $sArray = ''
    For $j = 0 To 11
    $sArray &= $aMFC[$j] & ';'
    Next
    $sFile = StringMid($aSource[$i], StringInStr($aSource[$i], '\', 0, -1) + 1)
    If $sSourcePath <> '' Then
    $sNewFolder = StringTrimLeft(StringLeft($aSource[$i], StringInStr($aSource[$i], '\', 0, -1)), StringLen($sSourcePath))
    If Not FileExists($sDestPath & $sNewFolder) Then
    If Not DirCreate($sDestPath & $sNewFolder) Then Return SetError(3, 0, 0)
    EndIf
    EndIf
    If $sFile = '' Then ContinueLoop
    $k = 0
    While $bOverWrite = False And FileExists($sDestPath & $sNewFolder & $sFile)
    $k += 1
    $sFile = $sPreFix & $k & "_" & StringMid($aSource[$i], StringInStr($aSource[$i], '\', 0, -1) + 1)
    WEnd
    $aReturn[$i] = $sDestPath & $sNewFolder & $sFile
    $sShowSource = StringRegExpReplace($aSource[$i], '(.{15})(.*)(.{35})', '$1' & '[...]' & '$3')
    GUICtrlSetData($aMFC[1], 'Kopiere Datei ' & @CRLF & '"' & $sShowSource & '"' & @CRLF & 'nach: "' & $sShowDest & '"')
    $ret = DllCall($DllKernel32, 'int', 'CopyFileExA', 'str', $aSource[$i], 'str', $aReturn[$i], 'ptr', $ptr, 'str', $sArray, 'int', 0, 'int', 0)
    ;~ ConsoleWrite('Return: ' & $ret[0] & @LF)
    If $ret[0] = 0 Then $aMFC[10] = True
    $aMFC[8] += FileGetSize($aSource[$i])
    Next
    DllClose($DllKernel32)
    DllCallbackFree($callback)
    GUIDelete($aMFC[0])
    DllClose($aMFC[11])
    Opt('GUICloseOnESC', $oldGUICloseOnESC)
    Return $aReturn
    EndFunc ;==>_MultiFileCopy

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

    Func __Progress($FileSize, $BytesTransferred, $StreamSize, $StreamBytesTransferred, $dwStreamNumber, $dwCallbackReason, $hSourceFile, $hDestinationFile, $lpData)
    Local $aSplit = StringSplit(StringTrimRight($lpData, 1), ";")
    If $aSplit[11] = 'True' Then Return 1
    Local $pos = GUIGetCursorInfo($aSplit[1])
    If _IsPressed('1B', Int($aSplit[12])) Then Return 1
    If _IsPressed('01', Int($aSplit[12])) And ($pos[4] = Int($aSplit[7])) Then Return 1
    Local $sPercent = Round($BytesTransferred / $FileSize * 100, 0), $iTime, $iTotalTime, $iTransferRate
    Local $sPercentAll = Round(($aSplit[9] + $BytesTransferred) / $aSplit[8] * 100, 0)
    $iTime = TimerDiff($aSplit[10])
    $iTotalTime = Ceiling($iTime / 1000 / ($sPercentAll + 0.1) * 100)
    ;~ $iTransferRate = _StringAddThousandsSep(Int($aSplit[8] / $iTotalTime / 1000), '.', ',')
    GUICtrlSetData($aSplit[3], $sPercent & ' %')
    GUICtrlSetData($aSplit[5], $sPercent)
    GUICtrlSetData($aSplit[4], $sPercentAll & ' % Zeit: ' & Int($iTime / 1000) & '/' & $iTotalTime & ' s (' & $iTransferRate & ' KB/s)')
    GUICtrlSetData($aSplit[6], $sPercentAll)
    EndFunc ;==>__Progress

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

    Func __ProgressCreate(ByRef $aMFC)
    If Not IsDeclared('WS_POPUPWINDOW') Then Local Const $WS_POPUPWINDOW = 0x80880000
    If Not IsDeclared('WS_EX_TOPMOST') Then Local Const $WS_EX_TOPMOST = 0x00000008
    If Not IsDeclared('WS_EX_TOOLWINDOW') Then Local Const $WS_EX_TOOLWINDOW = 0x00000080
    If Not IsDeclared('WS_EX_COMPOSITED') Then Local Const $WS_EX_COMPOSITED = 0x02000000
    $aMFC[0] = GUICreate('MultiFileCopy', 480, 220, -1, -1, $WS_POPUPWINDOW, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW, $WS_EX_COMPOSITED))
    $aMFC[1] = GUICtrlCreateLabel('', 10, 10, 460, 65)
    GUICtrlSetFont(-1, 10, 400, 0, 'Courier New')
    GUICtrlCreateLabel('Datei:', 10, 83, 60, 16)
    GUICtrlSetFont(-1, 11, 600, 0, 'Courier New')
    $aMFC[2] = GUICtrlCreateLabel('0 %', 80, 83, 390, 16)
    GUICtrlSetFont(-1, 11, 600, 0, 'Courier New')
    $aMFC[4] = GUICtrlCreateProgress(10, 100, 460, 20)
    GUICtrlCreateLabel('Gesamt:', 10, 133, 60, 16)
    GUICtrlSetFont(-1, 11, 600, 0, 'Courier New')
    $aMFC[3] = GUICtrlCreateLabel('0 %', 80, 133, 390, 16)
    GUICtrlSetFont(-1, 11, 600, 0, 'Courier New')
    $aMFC[5] = GUICtrlCreateProgress(10, 150, 460, 20)
    $aMFC[6] = GUICtrlCreateButton('Abbrechen', 200, 185, 75, 25)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    GUISetState()
    EndFunc ;==>__ProgressCreate

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

    ;==================================================================================================
    ; Function Name: _GetFilesFolder_Rekursiv($sPath [, $sExt='*' [, $iDir=-1 [, $iRetType=0 ,[$sDelim='0']]]])
    ; Description: Rekursive Auflistung von Dateien und/oder Ordnern
    ; Anpassung: Verzeichnisgröße ermitteln für _MultiFileCopy ($strSize)
    ; Parameter(s): $sPath der Basispfad für die Auflistung ('.' -aktueller Pfad, '..' -Parentpfad)
    ; $sExt Erweiterung für Dateiauswahl '*' oder -1 für alle (Standard)
    ; $iDir -1 Dateien+Ordner(Standard), 0 nur Dateien, 1 nur Ordner
    ; optional: $iRetType 0 gibt Array, 1 gibt String zurück
    ; optional: $sDelim legt Trennzeichen für Stringrückgabe fest
    ; 0 -@CRLF (Standard) 1 -@CR 2 -@LF 3 -';' 4 -'|'
    ; Return Value(s): Array (Standard) od. String mit den gefundenen Pfaden der Dateien und/oder Ordner
    ; Array[0] enthält die Anzahl der gefundenen Dateien/Ordner
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;==================================================================================================
    Func _GetFilesFolder_Rekursiv($sPath, $sExt='*', $iDir=-1, $iRetType=0, $sDelim='0')
    Global $oFSO = ObjCreate('Scripting.FileSystemObject')
    Global $strFiles = ''
    Switch $sDelim
    Case '1'
    $sDelim = @CR
    Case '2'
    $sDelim = @LF
    Case '3'
    $sDelim = ';'
    Case '4'
    $sDelim = '|'
    Case Else
    $sDelim = @CRLF
    EndSwitch
    If ($iRetType < 0) Or ($iRetType > 1) Then $iRetType = 0
    If $sExt = -1 Then $sExt = '*'
    If ($iDir < -1) Or ($iDir > 1) Then $iDir = -1
    _ShowSubFolders($oFSO.GetFolder($sPath),$sExt,$iDir,$sDelim)
    If $iRetType = 0 Then
    Local $aOut
    $aOut = StringSplit(StringTrimRight($strFiles, StringLen($sDelim)), $sDelim, 1)
    If $aOut[1] = '' Then
    ReDim $aOut[1]
    $aOut[0] = 0
    EndIf
    Return $aOut
    Else
    Return StringTrimRight($strFiles, StringLen($sDelim))
    EndIf
    EndFunc

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

    Func _ShowSubFolders($Folder, $Ext='*', $Dir=-1, $Delim=@CRLF)
    If Not IsDeclared("strFiles") Then Global $strFiles = ''
    If ($Dir = -1) Or ($Dir = 0) Then
    For $file In $Folder.Files
    If $Ext <> '*' Then
    If StringRight($file.Name, StringLen($Ext)) = $Ext Then
    $strSize += $file.size
    $strFiles &= $file.Path & $Delim
    EndIf
    Else
    $strSize += $file.size
    $strFiles &= $file.Path & $Delim
    EndIf
    Next
    EndIf
    For $Subfolder In $Folder.SubFolders
    If ($Dir = -1) Or ($Dir = 1) Then $strFiles &= $Subfolder.Path & '\' & $Delim
    _ShowSubFolders($Subfolder, $Ext, $Dir, $Delim)
    Next
    EndFunc

    [/autoit]

    danke nochmal für deine Hilfe Raupi ;)

    • Offizieller Beitrag

    Bei deinem Code werden aber nur Dateien kopiert, die 2 Tage alt sind und nicht welche die nicht älter als 2 Tage sind. ;)

  • Ich hatte die Berechnung anpassen müssen. Jetzt werden nur noch die Dateien kopiert, die dem Datum entsprechen, dass ich zu beginn des Scripts in der InputBox eintrage.

    In meinem vorherigen Post ist die "für mich" aktuelle Version gespoilert. Man könnte jetzt noch einbauen, dass die "Start/Zielpfade" zu beginn abgefragt werden, aber für mich ist das nicht nötig, es bleibt in meinem Fall immer der gleiche Startpfad.

    Nochmals danke!! :rock: