• Offizieller Beitrag

    Ich brauchte gerade eine Kopierfunktion für mehrere Dateien und Tom99 hatte in "Hilfe & Unterstützung" eine Copy-Funktion mit DllCallback gepostet. Da habe ich die mal etwas ausgebaut:

    Spoiler anzeigen
    [autoit]


    ;===werden benötigt=============================================================
    #include<String.au3>
    #include<Misc.au3>
    Global $strFiles = '', $strSize = 0
    ;===============================================================================

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

    ;===Beispiel 1 (erstellen der Datei "!copydata.mfc" im Quellverzeichnis)========
    Global $sSourcePath = 'C:\Programme\AutoIt3\Examples\'

    [/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 = 'C:\Programme\AutoIt3\Examples\'
    Global $sDestinationPath = @ScriptDir & '\Tmp1'; 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<String.au3>
    ; #include<Misc.au3>
    ; 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 $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]
    FileWriteLine($hFile, $aSource[$i])
    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]

    ScreenShot:
    IOM302_fix.zip

    - Die Funktion kann auch ein ganzes Verzeichnis (rekursiv) kopieren, wenn als Quelle kein Array, sondern ein Verzeichnispfad angegeben wird.
    - Es wird dann die Verzeichnisstruktur des Übergabepfades übernommen und im Zielpfad erstellt!
    - Beim kopieren einzelner Dateien muss im Übergabe-Array (für die zu kopierenden Dateien) der erste Eintrag die Anzahl der Dateien beinhalten!
    - Der Zielpfad wird erstellt, wenn er nicht existiert!
    - Abbruch per [ESC]-Taste oder über den [Abbrechen]-Button!
    - Wird der dritte Parameter auf "False" gesetzt werden evtl. vorhandene Dateien nicht überschrieben. Die neuen Dateien bekommen dann einen PreFix vorangestellt, den man als 4. Parameter angeben kann.
    - Die Funktion gibt ein Array mit den kopierten Dateien zurück.

    Im Script befinden sich drei Beispiele, die den Aufruf verdeutlichen sollen.

    Zum rekursiven einlesen des Quellverzeichnisses benutze ich (mal wieder) die Funktion _GetFilesFolder_Rekursiv() von BugFix. :thumbup:

    Neue Version ( 26.01.09 )

    Weil das einlesen der Verzeichnisstruktur u.U. so lange dauern kann, habe ich MultiFileCopy (MFC) dahingehend geändert, dass man vorab (einmalig) diese Daten einlesen kann (siehe Beispiel). Dazu muss man die Funktion nur mit dem Quellverzeichnis (ohne weitere Parameter) aufrufen. Die Daten werden dann in einer Datei "!copydata.mfc" im Quellverzeichnis abgelegt. Will man später dieses Verzeichnis mit MultiFileCopy irgendwohin kopieren, so sieht MFC nach, ob sich im Quellverzeichnis eine solche Datei befindet und liest die Daten aus dieser Datei, statt das Verzeichnis zeitaufwendig neu einzulesen.
    Achtung! Wenn sich die Dateien und/oder die Ordnerstruktur geändert haben, so muss man die Datei "!copydata.mfc" neu erstellen lassen, ansonsten würde MFC die "alten" Daten benutzen.

  • Ich guck mal :) Ich glaub die funktion geht auch ganz ohne Globals mal sehen :)
    Ok man kann jetzt schon mal abrrechen, die position des Buttons sollte man anpassen.

    [autoit]

    #cs ----------------------------------------------------------------------------

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

    AutoIt Version: 3.2.12.1
    Author: myName

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

    Script Function:
    Template AutoIt script.

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

    #ce ----------------------------------------------------------------------------

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

    ; Script Start - Add your code below here

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

    #include<String.au3>
    #include<WindowsConstants.au3>
    #include <GUIConstantsEx.au3>

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

    Global $hGUI, $hCopy, $hPercent, $hPercentAll, $hProgressFile, $hProgressAll, $hCancel, $iTotalFileSize, $iTotalBytesTransferred, $hTimer, $iStop = 0
    Dim $aSourceFiles[3] = ['C:\test1.zip', 'C:\test2.zip', 'C:\test3.zip'] ; Die Dateien in diesem Array werden kopiert
    Dim $sDestinationPath = @ScriptDir ; Zielpfad (muss existieren)

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

    _MultiFileCopy($aSourceFiles, $sDestinationPath)

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

    opt ( "GUIOnEventMode", 1)

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

    Func _MultiFileCopy(ByRef $aSource, $sDestPath)
    If Not IsArray($aSource) Then Return SetError(1, 0, 0)
    If Not FileExists($sDestPath) Then Return SetError(2, 0, 0)
    If StringRight($sDestPath, 1) <> '\' Then $sDestPath &= '\'
    Local $aFileSize[UBound($aSource)]
    For $i = 0 To UBound($aSource) - 1
    $aFileSize[$i] = FileGetSize($aSource[$i])
    $iTotalFileSize += $aFileSize[$i]
    Next
    Local $callback = DllCallbackRegister('__Progress', 'int', 'uint64;uint64;uint64;uint64;dword;dword;ptr;ptr;ptr')
    Local $ptr = DllCallbackGetPtr($callback)
    ;~ DllStructCreate ( "int totalsize;"
    __ProgressCreate()
    $hTimer = TimerInit()
    For $i = 0 To UBound($aSource) - 1
    $sFile = StringMid($aSource[$i], StringInStr($aSource[$i], '\', 0, -1) + 1)
    GUICtrlSetData($hCopy, 'Kopiere Datei "' & $aSource[$i] & '"' & @CRLF & 'nach: "' & $sDestPath & '"')
    DllCall('kernel32.dll', 'int', 'CopyFileExA', 'str', $aSource[$i], 'str', $sDestPath & $sFile, 'ptr', $ptr, 'ptr', 0, 'int', 0, 'int', 0)
    $iTotalBytesTransferred += $aFileSize[$i]
    Next
    GUIDelete($hGUI)
    EndFunc

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

    Func __ProgressCreate()
    $hGUI = GUICreate('FileCopy', 380, 160, -1, -1, $WS_POPUPWINDOW)
    GUISetOnEvent($GUI_EVENT_CLOSE, "__stop")
    $hCopy = GUICtrlCreateLabel('', 10, 15, 360, 50)
    GUICtrlSetFont(-1, 10, 400, 0, 'Arial')
    GUICtrlCreateLabel('Datei:', 10, 64, 60, 16)
    GUICtrlSetFont(-1, 9, 600, 0, 'Arial')
    $hPercent = GUICtrlCreateLabel('0 %', 70, 64, 300, 16)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    $hProgressFile = GUICtrlCreateProgress(10, 80, 360, 20)
    GUICtrlCreateLabel('Gesamt:', 10, 114, 60, 16)
    GUICtrlSetFont(-1, 9, 600, 0, 'Arial')
    $hPercentAll = GUICtrlCreateLabel('0 %', 70, 114, 300, 16)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    $hProgressAll = GUICtrlCreateProgress(10, 130, 360, 20)
    $stop = GUICtrlCreateButton ( "stop", 0, 0 )
    GUISetOnEvent($stop, "__stop")
    GUISetState()
    Sleep(200)
    EndFunc

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

    func __stop ()
    $iStop = 1
    EndFunc

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

    Func __Progress($FileSize, $BytesTransferred, $StreamSize, $StreamBytesTransferred, $dwStreamNumber, $dwCallbackReason, $hSourceFile, $hDestinationFile, $lpData)
    if $iStop = 1 Then
    Return 1
    EndIf

    Local $sPercent = Round($BytesTransferred / $FileSize * 100, 0), $iTime, $iTotalTime, $iTransferRate
    Local $sPercentAll = Round(($iTotalBytesTransferred + $BytesTransferred) / $iTotalFileSize * 100, 0)
    If GUICtrlRead($hProgressFile) <> $sPercent Then
    $iTime = TimerDiff($hTimer)
    $iTotalTime = Ceiling($iTime / 1000 / $sPercentAll * 100)
    $iTransferRate = _StringAddThousandsSep(Int($iTotalFileSize / $iTotalTime / 1000), '.', ',')
    GUICtrlSetData($hPercent, $sPercent & ' %')
    GUICtrlSetData($hProgressFile, $sPercent)
    GUICtrlSetData($hPercentAll, $sPercentAll & ' % Zeit: ' & Int($iTime / 1000) & ' / ' & $iTotalTime & ' s (' & $iTransferRate & ' KB/s)')
    GUICtrlSetData($hProgressAll, $sPercentAll)
    Sleep(5)
    EndIf
    EndFunc

    [/autoit]

    Einmal editiert, zuletzt von Tom99 (23. September 2008 um 14:21)

    • Offizieller Beitrag

    Bei Deiner Änderung kann man aber erst nach einer Datei abbrechen, weil der Button vorher keinen Event auslöst.
    Aber Du hast mich auf eine Idee gebracht, die sogar funktioniert (siehe Post #1). :)
    Jetzt kann man die Funktion mit der [ESC]-Taste oder mit Mausklick auf [Abbrechen] abbrechen. Das reicht mir völlig. Vielen Dank! :thumbup:

  • Schön gelöst :) Ich finds lustig das ich so einem alten Hasen noch auf die Sprünge helfen konnte.
    Noch was, warum $bStop? Man kann doch gleich return 1 machen = 1 Globale Variable weniger :rock:

    [autoit]


    Local $pos = GUIGetCursorInfo()
    If _IsPressed('1B', $dll) Then Return 1
    If _IsPressed('01', $dll) And ($pos[4] = $hCancel) then Return 1

    [/autoit]
  • ciao!

    Ist es irgenwie auch möglich ganze Verzeichnisbäume zu kopieren, oder muss man komplett alles umbauen ?

  • Also das heisst ich muss die

    Code
    $aSourceFiles bearbeiten?

    Test:

    Global $aSourceFiles[1] = ['\\server01\transfer']
    Global $aSourceFiles[1] = ['\\server01\transfer\']
    Global $aSourceFiles[1] = ['\\server01\transfer\*.*']
    Global $aSourceFiles[1] = ["\\server01\transfer"]
    Global $aSourceFiles[1] = ["\\server01\transfer\"]
    Global $aSourceFiles[1] = ["\\server01\transfer\*.*"]

    So einfach funktioniert es nicht, habe ich was flasch gemacht? :)

    • Offizieller Beitrag

    @progandy: Ich habe das jetzt dahingehend geändert, dass Array[0] die Anzahl der zu kopierenden Dateien enthalten muss (siehe Post #1).

    @satinez: schau Dir das Beispiel in der neuen Version an. Dort wird _FileListToArray benutzt.
    Willst Du hingegen Dateien von unterschiedlichen Pfaden kopieren, musst Du die "von Hand" ins Array packen:

    [autoit]

    Global $aSourceFiles[4] = [3, 'c:\bla.gif', 'd:\blub\blablub.jpg', 'e:\bli\bla.zip']

    [/autoit]
  • Ok ich hab mal wieder ein wenig gebastellet :)
    Rein von der Theroie sollte es jetzt ohne Globals gehen. Leider bricht der Script mit Exit Code -1073741819 ab.
    Naja vielleicht findet ihr ja das Problem.

    Spoiler anzeigen
    [autoit]

    Opt('GUICloseOnESC', 0)

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

    Global $aSourceFiles[3] = ['C:\test1.zip', 'C:\test2.zip', 'C:\test3.zip'] ; Die Dateien in diesem Array werden kopiert
    Global $sDestinationPath = @ScriptDir ; Zielpfad (muss existieren)

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

    _MultiFileCopy($aSourceFiles, $sDestinationPath)

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

    Func _MultiFileCopy(ByRef $aSource, $sDestPath)
    Local $aMFC[12] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, False, DllOpen('user32.dll')]
    If Not IsArray($aSource) Then Return SetError(1, 0, 0)
    If Not FileExists($sDestPath) Then Return SetError(2, 0, 0)
    If StringRight($sDestPath, 1) <> '\' Then $sDestPath &= '\'
    Local $aFileSize[UBound($aSource)]
    For $i = 0 To UBound($aSource) - 1
    $aFileSize[$i] = FileGetSize($aSource[$i])
    $aMFC[7] += $aFileSize[$i]
    Next
    Local $callback = DllCallbackRegister('__Progress', 'int', 'uint64;uint64;uint64;uint64;dword;dword;ptr;ptr;str')
    Local $ptr = DllCallbackGetPtr($callback)
    ;~ Local $data = DllStructCreate ("int")
    ;~ DllStructSetData ( $data, 1, 50)
    ;~ ConsoleWrite (DllStructGetData ($data,1))
    __ProgressCreate($aMFC)
    $aMFC[9] = TimerInit()
    For $i = 0 To UBound($aSource) - 1
    $sFile = StringMid($aSource[$i], StringInStr($aSource[$i], '\', 0, -1) + 1)
    $sArray = $aMFC[0] & ";" & $aMFC[1] & ";" & $aMFC[2] & ";" & $aMFC[3] & ";" & $aMFC[4] & ";" & $aMFC[5] & ";" & $aMFC[6] & ";"
    $sArray &= $aMFC[7] & ";" & $aMFC[8] & ";" & $aMFC[9] & ";" & $aMFC[10] & ";" & $aMFC[11]
    GUICtrlSetData($aMFC[1], 'Kopiere Datei "' & $aSource[$i] & '"' & @CRLF & 'nach: "' & $sDestPath & '"')
    $ret = DllCall('kernel32.dll', 'int', 'CopyFileExA', 'str', $aSource[$i], 'str', $sDestPath & $sFile, 'ptr', $ptr, 'str', $sArray , 'int', 0, 'int',0 )
    ;~ _ArrayDisplay ($ret)
    ConsoleWrite ("Return: " & $ret[0] & @lf)
    if $ret[0] = 0 Then
    $aMFC[10] = True
    EndIf
    $aMFC[8] += $aFileSize[$i]
    Next
    GUIDelete($aMFC[0])
    DllClose($aMFC[11])
    EndFunc ;==>_MultiFileCopy

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

    Func __ProgressCreate(ByRef $aMFC)
    $aMFC[0] = GUICreate('FileCopy', 380, 200, -1, -1, $WS_POPUPWINDOW)
    $aMFC[1] = GUICtrlCreateLabel('', 10, 15, 360, 50)
    GUICtrlSetFont(-1, 10, 400, 0, 'Arial')
    GUICtrlCreateLabel('Datei:', 10, 64, 60, 16)
    GUICtrlSetFont(-1, 9, 600, 0, 'Arial')
    $aMFC[2] = GUICtrlCreateLabel('0 %', 70, 64, 300, 16)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    $aMFC[4] = GUICtrlCreateProgress(10, 80, 360, 20)
    GUICtrlCreateLabel('Gesamt:', 10, 114, 60, 16)
    GUICtrlSetFont(-1, 9, 600, 0, 'Arial')
    $aMFC[3] = GUICtrlCreateLabel('0 %', 70, 114, 300, 16)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    $aMFC[5] = GUICtrlCreateProgress(10, 130, 360, 20)
    $aMFC[6] = GUICtrlCreateButton('Abbrechen', 150, 165, 75, 25)
    GUISetState()
    Sleep(200)
    EndFunc ;==>__ProgressCreate

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

    Func __Progress($FileSize, $BytesTransferred, $StreamSize, $StreamBytesTransferred, $dwStreamNumber, $dwCallbackReason, $hSourceFile, $hDestinationFile, $lpData)
    Local $aSplit = StringSplit ($lpData, ";")
    if $aSplit[11] = 'True' Then Return 1
    Local $pos = GUIGetCursorInfo(Int($aSplit[1]))
    If _IsPressed('1B', int($aSplit[12])) Then Return 1
    ;~ ConsoleWrite (VarGetType ($aMFC[9]) & "|" & $aMFC[9] & "|" & $aSplit[10] & @lf)
    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((int($aSplit[9]) + $BytesTransferred) / $aMFC[7] * 100, 0)
    If GUICtrlRead(int($aSplit[5])) <> $sPercent Then
    $iTime = TimerDiff(Number ($aSplit[10]))
    $iTotalTime = Ceiling($iTime / 1000 / $sPercentAll * 100)
    $iTransferRate = _StringAddThousandsSep(Int(int($aSplit[8]) / $iTotalTime / 1000), '.', ',')
    GUICtrlSetData(int($aSplit[3]), $sPercent & ' %')
    GUICtrlSetData(int($aSplit[5]), $sPercent)
    GUICtrlSetData(int($aSplit[4]), $sPercentAll & ' % Zeit: ' & Int($iTime / 1000) & ' / ' & $iTotalTime & ' s (' & $iTransferRate & ' KB/s)')
    GUICtrlSetData(int($aSplit[6]), $sPercentAll)
    Sleep(10)
    EndIf
    EndFunc ;==>__Progress

    [/autoit]
  • habe es jetzt hinbekommen, aber er kopiert die Ordnerstruktur nicht mit.

    [autoit]

    ; ---Beispiel----------------------------------------------------------------------------
    #Include<File.au3>
    ;~ #Include<Array.au3>
    Global $sPath = '\\Server01\transfer\'
    Global $sDestinationPath = @ScriptDir & "\files" ; Zielpfad (muss existieren)

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

    Global $aSourceFiles = _FileListToArray($sPath, '*.*', 0)
    For $i = 1 To $aSourceFiles[0]
    $aSourceFiles[$i] = $sPath & $aSourceFiles[$i]
    Next
    ;_ArrayDisplay($aSourceFiles)
    _MultiFileCopy($aSourceFiles, $sDestinationPath) ; $aSourceFiles[0] muss die Anzahl der Elemente enthalten
    ; ---------------------------------------------------------------------------------------

    [/autoit]

    Kann ich ihm sagen, er soll auch versteckte kopieren? Files wie auch Ordner?


    lg satinez

  • Tom: Du hast 1mal umbenennen vergessen ;)
    Zeiel 71 muss so sein:

    [autoit]

    Local $sPercentAll = Round((int($aSplit[9]) + $BytesTransferred) / $aSplit[8] * 100, 0)

    [/autoit]

    //Edit: Mit folgendemSkript kann man für jede Datei ein SubDirectory angeben, in das kopiert werden soll :)

    Spoiler anzeigen
    [autoit]

    Opt('GUICloseOnESC', 0)
    #include <GuiConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <WinAPI.au3>
    #include <Misc.au3>
    #include <String.au3>
    Global $aSourceFiles[3][2] = [['C:\betaversion.ini',"testdir1"], ['C:\mbrfix.exe'], ['C:\test3.zip']] ; Die Dateien in diesem Array werden kopiert
    Global $sDestinationPath = @DesktopDir & "\testpath" ; Zielpfad (muss existieren)
    DirCreate($sDestinationPath)
    ShellExecute($sDestinationPath)
    _MultiFileCopyEx($aSourceFiles, $sDestinationPath)

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

    Func _MultiFileCopyEx(ByRef $aSource, $sDestPath)
    Local $aMFC[12] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, False, DllOpen('user32.dll')]
    If Not IsArray($aSource) Then Return SetError(1, 0, 0)
    If UBound($aSource,0)<>2 Or UBound($aSource,2)<>2 Then Return SetError(1, 0, 0)
    If Not FileExists($sDestPath) Then Return SetError(2, 0, 0)
    $sDestPath = StringReplace($sDestPath,"/","\")
    If StringRight($sDestPath, 1) <> '\' Then $sDestPath &= '\'
    Local $aFileSize[UBound($aSource)]
    For $i = 0 To UBound($aSource) - 1
    If $i = 0 And $aSource[$i][0] = (UBound($aSource)-1) Then ContinueLoop
    $aSource[$i][1] = StringReplace($aSource[$i][1],"/","\")
    If StringLeft($aSource[$i][1],1) = "\" Then $aSource[$i][1] = StringTrimLeft($aSource[$i][1],1)
    If StringRight($aSource[$i][1],1) <> "\" Then $aSource[$i][1] &= "\"
    If $aSource[$i][1] = "\" Then $aSource[$i][1] = ""
    $aFileSize[$i] = FileGetSize($aSource[$i][0])
    $aMFC[7] += $aFileSize[$i]
    Next
    Local $callback = DllCallbackRegister('__Progress', 'int', 'uint64;uint64;uint64;uint64;dword;dword;ptr;ptr;str')
    Local $ptr = DllCallbackGetPtr($callback)
    ;~ Local $data = DllStructCreate ("int")
    ;~ DllStructSetData ( $data, 1, 50)
    ;~ ConsoleWrite (DllStructGetData ($data,1))
    __ProgressCreate($aMFC)
    $aMFC[9] = TimerInit()
    For $i = 0 To UBound($aSource) - 1
    If $i = 0 And $aSource[$i][0] = (UBound($aSource)-1) Then ContinueLoop
    $sFile = StringMid($aSource[$i][0], StringInStr($aSource[$i][0], '\', 0, -1) + 1)
    $sArray = $aMFC[0] & ";" & $aMFC[1] & ";" & $aMFC[2] & ";" & $aMFC[3] & ";" & $aMFC[4] & ";" & $aMFC[5] & ";" & $aMFC[6] & ";"
    $sArray &= $aMFC[7] & ";" & $aMFC[8] & ";" & $aMFC[9] & ";" & $aMFC[10] & ";" & $aMFC[11]
    $pArray = DllStructCreate("char[" & (StringLen($sArray)+1) & "]")
    DllStructSetData($pArray,1,$sArray)
    GUICtrlSetData($aMFC[1], 'Kopiere Datei "' & $aSource[$i][0] & '"' & @CRLF & 'nach: "' & $sDestPath&$aSource[$i][1] & '"')
    DirCreate($sDestPath &$aSource[$i][1])
    $ret = DllCall('kernel32.dll', 'int', 'CopyFileExA', 'str', $aSource[$i][0], 'str', $sDestPath & $aSource[$i][1] & $sFile, 'ptr', $ptr, 'str', $sArray , 'int', 0, 'int',0 )
    ;~ _ArrayDisplay ($ret)
    ConsoleWrite ("Return: " & $ret[0] & @lf)
    if $ret[0] = 0 Then
    $aMFC[10] = True
    EndIf
    $aMFC[8] += $aFileSize[$i]
    Next
    GUIDelete($aMFC[0])
    DllClose($aMFC[11])
    EndFunc ;==>_MultiFileCopy

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

    Func __ProgressCreate(ByRef $aMFC)
    $aMFC[0] = GUICreate('FileCopy', 380, 200, -1, -1, $WS_POPUPWINDOW)
    $aMFC[1] = GUICtrlCreateLabel('', 10, 15, 360, 50)
    GUICtrlSetFont(-1, 10, 400, 0, 'Arial')
    GUICtrlCreateLabel('Datei:', 10, 64, 60, 16)
    GUICtrlSetFont(-1, 9, 600, 0, 'Arial')
    $aMFC[2] = GUICtrlCreateLabel('0 %', 70, 64, 300, 16)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    $aMFC[4] = GUICtrlCreateProgress(10, 80, 360, 20)
    GUICtrlCreateLabel('Gesamt:', 10, 114, 60, 16)
    GUICtrlSetFont(-1, 9, 600, 0, 'Arial')
    $aMFC[3] = GUICtrlCreateLabel('0 %', 70, 114, 300, 16)
    GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
    $aMFC[5] = GUICtrlCreateProgress(10, 130, 360, 20)
    $aMFC[6] = GUICtrlCreateButton('Abbrechen', 150, 165, 75, 25)
    GUISetState()
    Sleep(200)
    EndFunc ;==>__ProgressCreate

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

    Func __Progress($FileSize, $BytesTransferred, $StreamSize, $StreamBytesTransferred, $dwStreamNumber, $dwCallbackReason, $hSourceFile, $hDestinationFile, $lpData)
    Local $aSplit = StringSplit ($lpData, ";")
    if $aSplit[11] = 'True' Then Return 1
    Local $pos = GUIGetCursorInfo(Int($aSplit[1]))
    If _IsPressed('1B', int($aSplit[12])) Then Return 1
    ;~ ConsoleWrite (VarGetType ($aMFC[9]) & "|" & $aMFC[9] & "|" & $aSplit[10] & @lf)
    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((int($aSplit[9]) + $BytesTransferred) / $aSplit[8] * 100, 0)
    If GUICtrlRead(int($aSplit[5])) <> $sPercent Then
    $iTime = TimerDiff(Number ($aSplit[10]))
    $iTotalTime = Ceiling($iTime / 1000 / $sPercentAll * 100)
    $iTransferRate = _StringAddThousandsSep(Int(int($aSplit[8]) / $iTotalTime / 1000), '.', ',')
    GUICtrlSetData(int($aSplit[3]), $sPercent & ' %')
    GUICtrlSetData(int($aSplit[5]), $sPercent)
    GUICtrlSetData(int($aSplit[4]), $sPercentAll & ' % Zeit: ' & Int($iTime / 1000) & ' / ' & $iTotalTime & ' s (' & $iTransferRate & ' KB/s)')
    GUICtrlSetData(int($aSplit[6]), $sPercentAll)
    Sleep(10)
    EndIf
    EndFunc ;==>__Progress

    [/autoit]

    Einmal editiert, zuletzt von progandy (28. September 2008 um 15:22)