Code : Tout sélectionner
#include<String.au3>
#include<Misc.au3>
Global $strFiles = '', $strSize = 0
; All files from the array are copied into the target directory
; Array[0], the number of files to copy contained
Global $aSource[4] = [3, @SystemDir & '\shell32.dll', @SystemDir & '\mspaint.exe', @SystemDir & '\oembios.bin']
Global $sDestinationPath = @ScriptDir & '\Tmp2'; Target path (may be created)
Global $aReturn = _MultiFileCopy($aSource, $sDestinationPath, True)
;===============================================================================
; Function Name: _MultiFileCopy
; Description:: Copies multiple files with progressbar
; Parameter(s): Array of files to copy or source path,
; Target path,
; overwrite? [True/False],
; If overwrite = True, prefix to overwrite
; Return Value(s): Array containing the copied files
; Requirement(s): Global $strFiles = '', $strSize = 0
; #include<String.au3>
; #include<Misc.au3>
; Author(s): Tom99, progandy, eukalyptus and Oscar (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('Please wait! Directory will be read!', @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
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 & ' % Time: ' & Int($iTime / 1000) & '/' & $iTotalTime & ' s (' & $iTransferRate & ' KB/s)')
GUICtrlSetData($aSplit[6], $sPercentAll)
EndFunc ;==>__Progress
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('File:', 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('Total:', 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('Cancel', 200, 185, 75, 25)
GUICtrlSetFont(-1, 9, 400, 0, 'Arial')
GUISetState()
EndFunc ;==>__ProgressCreate
;==================================================================================================
; Function Name: _GetFilesFolder_Rekursiv($sPath [, $sExt='*' [, $iDir=-1 [, $iRetType=0 ,[$sDelim='0']]]])
; Description: Recursive list of files and / or folders
; Adaptation: directory size determined for _MultiFileCopy ($strSize)
; Parameter(s): $sPath the base path for the listing ('.' -current path, '..' -Parent path)
; $sExt Extension to file selector '*' or -1 for all (default)
; $iDir -1 Files folder (default), 0 only files, 1 folders only
; optional: $iRetType 0 returns Array, 1 returns String
; optional: $sDelim specifies the separator for String Return
; 0 -@CRLF (Default) 1 -@CR 2 -@LF 3 -';' 4 -'|'
; Return Value(s): Array (Default) od string with the found paths of files and / or folders
; Array[0] contains the number of files / folders
; Author(s): BugFix (bugfix@autoit.de)
;==================================================================================================
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
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