NDog Posted June 15, 2011 Posted June 15, 2011 (edited) I have this code taken from the german forum and tried to modify to my needs. The problem is if i click the mouse or click somewhere or press a key on the keyboard the script exits. I cannot figure out why it exits if I press a button or move the mouse away. I would like the script to keep running if i click the mouse somewhere or press a key. I would like this script to copy folders, show the progress bar, have no option to cancel and not close if i press escape or click somewhere else. Just run! _MultiFileCopy.au3 expandcollapse popup;http://www.autoit.de/index.php?page=Thread&threadID=7923&pageNo=4a4690fea ;http://www.autoitscript.com/forum/topic/113446-replacement-for-stringaddthousandssep/ ;===werden benötigt============================================================= #include<String.au3> #include<Misc.au3> #include<array.au3> Global $strFiles = '', $strSize = 0, $anzgesamt = 0, $anz = 0 ;=============================================================================== #cs ;===Beispiel 1 (erstellen der Datei "!copydata.mfc" im Quellverzeichnis)======== Global $sSourcePath = 'C:\Programme\AutoIt3\Examples\' Global $aReturn = _MultiFileCopy($sSourcePath) MsgBox(0, 'MFC', '"!copydata.mfc" wurde erstellt!') ;=============================================================================== ;===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) Global $aReturn = _MultiFileCopy($sSourcePath, $sDestinationPath, False) ;=============================================================================== ;===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) Global $aReturn = _MultiFileCopy($aSource, $sDestinationPath, False) ;=============================================================================== #ce ;=============================================================================== ; 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 (www.autoit.de) ;=============================================================================== If $CMDLINE[0] <> 2 Then MsgBox(0,"", "Incorrect Parameters supplied") exit else _MultiFileCopy($CMDLINE[1], $CMDLINE[2]) endif Func _MultiFileCopy($aSource, $sDestPath = '', $bOverWrite = True, $sPreFix = '!Copy') 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 = DirGetSize($aSource) ;$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') $strSize = DirGetSize($aSource) $aSource = _RecursiveFileListToArray($sSourcePath, '', 1) 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 ;MsgBox(0,"",$aSource[0]) $anzgesamt = $aSource[0] 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, '(.{3})(.*)(.{50})', '$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] $anz = $anz +1 $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], '(.{3})(.*)(.{50})', '$1' & '[...]' & '$3') GUICtrlSetData($aMFC[1], 'Copying Files: ' & @CRLF & '"' & $sShowSource & '"' & @CRLF & 'Destination: ' & @CRLF & '"' & $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]) 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 ' & $anz & '/' & $anzgesamt & ' (' & $iTransferRate & ' KB/s)') GUICtrlSetData($aSplit[6], $sPercentAll) ;$anz = $anz + 1 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', 520, 220, @DesktopWidth - 520, 20, $WS_POPUPWINDOW, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW, $WS_EX_COMPOSITED)) $aMFC[1] = GUICtrlCreateLabel('', 10, 10, 500, 65) GUICtrlSetFont(-1, 10, 400, 0, 'Courier New') GUICtrlCreateLabel('Current File:', 10, 83, 60, 16) GUICtrlSetFont(-1, 11, 600, 0, 'Courier New') $aMFC[2] = GUICtrlCreateLabel('0 %', 80, 83, 500, 16) GUICtrlSetFont(-1, 11, 600, 0, 'Courier New') $aMFC[4] = GUICtrlCreateProgress(10, 100,500, 20) GUICtrlCreateLabel('Total:', 10, 133, 60, 16) GUICtrlSetFont(-1, 11, 600, 0, 'Courier New') $aMFC[3] = GUICtrlCreateLabel('0 %', 80, 133, 440, 16) GUICtrlSetFont(-1, 11, 600, 0, 'Courier New') $aMFC[5] = GUICtrlCreateProgress(10, 150, 500, 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: 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 (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 ;=============================================================================== ; Function Name: _RecursiveFileListToArray($sPath[, $sPattern][, $iFlag][, $iFormat][, $iRecursion][, $sDelim]) ; Description:: gibt Verzeichnisse (rekursiv) und/oder Dateien zurück, die einem RegExp-Pattern entsprechen ; Parameter(s): $sPath = Startverzeichnis ; $sPattern = ein beliebiges RexExp-Pattern für die Auswahl ; $iFlag = Auswahl ; 0 = Dateien & Verzeichnisse ; 1 = nur Dateien ; 2 = nur Verzeichnisse ; $iFormat = Rückgabeformat ; 0 = String ; 1 = Array mit [0] = Anzahl ; 2 = Nullbasiertes Array ; $iRecursion = Verzeichnisse rekursiv durchsuchen ; 0 = Nein ; 1 = Ja ; $sDelim = Trennzeichen für die String-Rückgabe ; Requirement(s): AutoIt 3.3.0.0 ; Return Value(s): Array/String mit den gefundenen Dateien/Verzeichnissen ; Author(s): Oscar (www.autoit.de) ; Anregungen von: bernd670 (www.autoit.de) ;=============================================================================== Func _RecursiveFileListToArray($sPath, $sPattern = '', $iFlag = 0, $iFormat = 1, $iRecursion = 1, $sDelim = @CRLF) Local $hSearch, $sFile, $sReturn = '' If StringRight($sPath, 1) <> '\' Then $sPath &= '\' $hSearch = FileFindFirstFile($sPath & '*.*') If @error Or $hSearch = -1 Then Return SetError(1, 0, $sReturn) While True $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop If StringInStr(FileGetAttrib($sPath & $sFile), 'D') Then If StringRegExp($sPath & $sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 2) Then $sReturn &= $sPath & $sFile & '\' & $sDelim If $iRecursion Then $sReturn &= _RecursiveFileListToArray($sPath & $sFile & '\', $sPattern, $iFlag, 0) ContinueLoop EndIf If StringRegExp($sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 1) Then $sReturn &= $sPath & $sFile & $sDelim WEnd FileClose($hSearch) If $iFormat And $sReturn = '' Then Return StringSplit($sReturn, '', $iFormat) If $iFormat Then Return StringSplit(StringTrimRight($sReturn, StringLen($sDelim)), $sDelim, $iFormat) Return $sReturn EndFunc ConsoleWrite(_StringAddThousandsSep("61234567890.54321") & @CRLF) ConsoleWrite(_StringAddThousandsSep("-$123123.50") & @CRLF) ConsoleWrite(_StringAddThousandsSep("-8123.45") & @CRLF) ConsoleWrite(_StringAddThousandsSep("-123.45") & @CRLF) ConsoleWrite(_StringAddThousandsSep("-$25") & @CRLF) ConsoleWrite(_StringAddThousandsSep("-$hello") & @CRLF) ; Instead of :- ; "Local $rKey = "HKCU\Control Panel\International" ; If $sDecimal = -1 Then $sDecimal = RegRead($rKey, "sDecimal") ; If $sThousands = -1 Then $sThousands = RegRead($rKey, "sThousand") ", ; ; $sThousands = ",", $sDecimal = "." are function parameters. ; Func _StringAddThousandsSep($sString, $sThousands = ",", $sDecimal = ".") Local $aNumber, $sLeft, $sResult = "", $iNegSign = "", $DolSgn = "" If Number(StringRegExpReplace($sString, "[^0-9\-.+]", "\1")) < 0 Then $iNegSign = "-" ; Allows for a negative value If StringRegExp($sString, "\$") And StringRegExpReplace($sString, "[^0-9]", "\1") <> "" Then $DolSgn = "$" ; Allow for Dollar sign $aNumber = StringRegExp($sString, "(\d+)\D?(\d*)", 1) If UBound($aNumber) = 2 Then $sLeft = $aNumber[0] While StringLen($sLeft) $sResult = $sThousands & StringRight($sLeft, 3) & $sResult $sLeft = StringTrimRight($sLeft, 3) WEnd $sResult = StringTrimLeft($sResult, 1); Strip leading thousands separator If $aNumber[1] <> "" Then $sResult &= $sDecimal & $aNumber[1] ; Add decimal EndIf Return $iNegSign & $DolSgn & $sResult ; Adds minus or "" (nothing)and Adds $ or "" EndFunc ;==>_StringAddThousandsSep Test it like this _MultiFileCopy.au3 c:\test1 c:\test2 Edited June 15, 2011 by NDog
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now