taker4mdb Posted October 5, 2007 Share Posted October 5, 2007 Just something I was playing around with... it copies whole directories only (including all subfolders and files). The idea is that if an error is encountered when copying a large number of files, it won't stop copying (like Windows). It has two options - overwrite files and batch mode (batch mode was my first attempt at this, it uses a hidden batch file to copy the files, monitoring the batches output to count the number of files processed. It's not neat or pretty, but it seems to go a little faster, so I crammed it in there!) To use the batch mode, you need a batch file in the same directory as the script file (this gets deleted after it's used - made to be compiled with the .exe, extracted, executed, and deleted) Contents of batch file (named MBCOPYFILES.bat): @echo off xcopy %1 %2 /e /c /h /r /y And the script file: expandcollapse popup#include <GUIConstants.au3> #include <Array.au3> GUICreate("Mike's File Copier", 300, 136) GUICtrlCreateLabel("Copy files from directory:", 10, 10, 280, 13) $txtFromDir = GUICtrlCreateInput("", 10, 23, 215, 20, $ES_READONLY) $btnFromDir = GUICtrlCreateButton("Browse", 230, 23, 60, 20) GUICtrlCreateLabel("To directory:", 10, 53, 280, 13) $txtToDir = GUICtrlCreateInput("", 10, 66, 215, 20, $ES_READONLY) $btnToDir = GUICtrlCreateButton("Browse", 230, 66, 60, 20) $cbxOWMode = GUICtrlCreateCheckbox("Overwrite", 10, 96, 100, 13) $cbxBatMode = GUICtrlCreateCheckbox("Batch Mode", 10, 114, 100, 13) $btnCopy = GUICtrlCreateButton("Copy", 120, 102, 60, 20) GUISetState() While 1 $msg = GUIGetMsg() Switch $msg Case $cbxBatMode If GUICtrlRead($cbxBatMode) = $GUI_CHECKED Then GUICtrlSetState($cbxOWMode, $GUI_CHECKED) GUICtrlSetState($cbxOWMode, $GUI_DISABLE) Else GUICtrlSetState($cbxOWMode, $GUI_ENABLE) EndIf Case $btnFromDir GUICtrlSetData($txtFromDir, FileSelectFolder("Select source folder", "", 3)) Case $btnToDir GUICtrlSetData($txtToDir, FileSelectFolder("Select destination folder", "", 3)) Case $btnCopy If (GUICtrlRead($txtFromDir) = "") Or (GUICtrlRead($txtToDir) = "") Then ;Do nothing Else If GUICtrlRead($cbxBatMode) = $GUI_CHECKED Then ;Bat mode $Timer = TimerInit() mbBatchCopy(GUICtrlRead($txtFromDir), GUICtrlRead($txtToDir)) MsgBox(0, "Complete", "Copy completed in: " & Round(TimerDiff($Timer) / 1000, 0) & " seconds.") Else ;Normal mode $Timer = TimerInit() mbFileCopy(GUICtrlRead($txtFromDir), GUICtrlRead($txtToDir), mbGetOWMode()) MsgBox(0, "Complete", "Copy completed in: " & Round(TimerDiff($Timer) / 1000, 0) & " seconds.") EndIf EndIf Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd Func mbFileCopy($from, $to, $ow) Dim $SD[1] Dim $DD[1] $SD[0] = $from $DD[0] = $to If StringRight($SD[0], 1) <> "\" Then $SD[0] = $SD[0] & "\" EndIf If StringRight($DD[0], 1) <> "\" Then $DD[0] = $DD[0] & "\" EndIf $SDS = DirGetSize($SD[0], 1) $FS = 0 $FC = 0 Dim $EC[1] $EC[0] = 0 ProgressOn("Copying Files", "Initializing...", "0% Complete", -1, -1, 16) Do $Search = FileFindFirstFile($SD[0] & "*") If $Search = -1 Then ;Empty folder, continue with the next Else While 1 $CF = FileFindNextFile($Search) If @error Then ExitLoop If StringInStr(FileGetAttrib($SD[0] & $CF), "D") = 0 Then;Is file a directory? ;Copy file ProgressSet(Round(($FS / $SDS[0]) * 100, 0), Round(($FS / $SDS[0]) * 100, 0) & "% Complete" & @LF & "(" & $FC & " Files, " & Round($FS / 1048576, 2) & "MB)", "Copying file: " & StringTrimRight($CF, StringLen($CF) - 16) & "...") If FileCopy($SD[0] & $CF, $DD[0] & $CF, $ow) = 0 Then $EC[0] = $EC[0] + 1 _ArrayAdd($EC, $SD[0] & $CF) EndIf $FC = $FC + 1 $FS = $FS + FileGetSize($SD[0] & $CF) Else ;Create destination directory if it doesn't exist and queue directory ProgressSet(Round(($FS / $SDS[0]) * 100, 0), Round(($FS / $SDS[0]) * 100, 0) & "% Complete" & @LF & "(" & $FC & " Files, " & Round($FS / 1048576, 2) & "MB)", "Creating directory: " & StringTrimRight($CF, StringLen($CF) - 16) & "...") If FileExists($DD[0] & $CF) = 0 Then DirCreate($DD[0] & $CF) ProgressSet(Round(($FS / $SDS[0]) * 100, 0), Round(($FS / $SDS[0]) * 100, 0) & "% Complete" & @LF & "(" & $FC & " Files, " & Round($FS / 1048576, 2) & "MB)", "Creating directory: " & StringTrimRight($CF, StringLen($CF) - 16) & "...") _ArrayAdd($SD, $SD[0] & $CF & "\");"CurrentDir\FoundDir\" _ArrayAdd($DD, $DD[0] & $CF & "\");"DestDir\FoundDir\" EndIf WEnd EndIf If StringInStr(_ArrayToString($SD, "?"), "?") = 0 Then ExitLoop ProgressSet(Round(($FS / $SDS[0]) * 100, 0), Round(($FS / $SDS[0]) * 100, 0) & "% Complete" & @LF & "(" & $FC & " Files, " & Round($FS / 1048576, 2) & "MB)", "Removing directory from queue") FileClose($Search);Release search handle _ArrayDelete($SD, 0);---\ _ArrayDelete($DD, 0);----Remove exhausted directories from the queue Until 0 ProgressOff() ;Check for errors and write/open error log, if necessary If $EC[0] > 0 Then $EL = FileOpen("Error Log.txt", 2) FileWriteLine($EL, "Mike's File Copier - Error Log") FileWriteLine($EL, @MON & "/" & @MDAY & "/" & @YEAR & " - " & @HOUR & ":" & @MIN) FileWriteLine($EL, "") FileWriteLine($EL, "There following " & $EC[0] & " files were not copied:") $i = 0 For $i = 1 to $EC[0] FileWriteLine($EL, $EC[$i]) Next FileWriteLine($EL, "") FileWriteLine($EL, "-- End of error log --") FileWriteLine($EL, "") FileWriteLine($EL, "") FileClose($EL) Run("Notepad.exe Error Log.txt") EndIf EndFunc ;==>mbFileCopy Func mbBatchCopy($strFrom, $strTo) $numSourceFiles = DirGetSize($strFrom, 1) $numCopiedFiles = 0 If StringRegExp($strFrom, ".*\\$", 0) = 0 Then $strFrom = $strFrom & "\*.*" Else $strFrom = $strFrom & "*.*" EndIf If StringRegExp($strTo, ".*\\$", 0) = 0 Then $strTo = $strTo & "\" EndIf FileInstall("MBCOPYFILES.bat", "MBCOPYFILES.bat", 1) FileSetAttrib("MBCOPYFILES.bat", "+H") $CopyBatch = Run('MBCOPYFILES.bat "' & $strFrom & '" "' & $strTo & '"', "", @SW_HIDE, 2) ProgressOn("Copying Files", "Initializing...", "0% Complete") While ProcessExists($CopyBatch) $STDOUT = StringRegExp(StdoutRead($CopyBatch), ":.*.{3}\b", 3) _ArrayAdd($STDOUT, "ENDOFARRAY") $numCopiedFiles = $numCopiedFiles + mbArrayGetSize($STDOUT) ProgressSet(Round(($numCopiedFiles / $numSourceFiles[1]) * 100, 0), Round(($numCopiedFiles / $numSourceFiles[1]) * 100, 0) & "% Complete", $numCopiedFiles & " files copied") Sleep(100) WEnd ProgressOff() FileDelete("MBCOPYFILES.bat") EndFunc ;==>mbBatchCopy Func mbArrayGetSize($array) If IsArray($array) = 0 Then Return -1 EndIf $index = 0 $count = 0 While 1 If $array[$index] = "ENDOFARRAY" Then ExitLoop Else $count = $count + 1 $index = $index + 1 EndIf WEnd Return $count EndFunc ;==>mbArrayGetSize Func mbGetOWMode() If GUICtrlRead($cbxOWMode) = $GUI_CHECKED Then Return 1 Else Return 0 EndIf EndFunc ;==>mbGetRecMode Link to comment Share on other sites More sharing options...
crzftx Posted October 6, 2007 Share Posted October 6, 2007 (edited) looks great. I actually need to look through that. I have been trying to figure out how to do some of that for a little while, depending on how you did it. If you could give me a brief explanation on how you got it to copy over directories within directories without using DirCopy(), thatd be great, if not, I will look harder. EDIT: figured it out. You just added a new directory to the array (queue) and deleted the first in line (already used), continually searching the first for new files. A little wordy, and poor variable names..., but otherwise very nicely done. Edited October 6, 2007 by crzftx Link to comment Share on other sites More sharing options...
Real4U Posted October 19, 2007 Share Posted October 19, 2007 Hi there, It's pretty cool code and so nice of you to share your codes. I wanna check with you if there anyway to get the file size and modified date of the filter file. I attached my code below and your great suggestion is truly appreciated. In fact, the script is just to monitor the filter file name, size and modified date and to be reported in a text file. #Include <File.au3> #Include <Array.au3> $a = "C:\" $b = "C:\Temp\Report.txt" $FileList=_FileListToArray($a,"*.exe",1) If @Error=1 Then MsgBox (0,"","No Files\Folders Found.") Exit EndIf _ArrayDelete($Filelist,0) _FileWriteFromArray($b,$FileList,1) I just start to learn the autoit and try to understand better. Perhaps my code is not enhanced like yours. Link to comment Share on other sites More sharing options...
dabus Posted October 19, 2007 Share Posted October 19, 2007 have look at a real nice robocopy-gui. Link to comment Share on other sites More sharing options...
Real4U Posted October 22, 2007 Share Posted October 22, 2007 have look at a real nice robocopy-gui.Thank you so much. But I'm kinda lost how to use it perhaps you give me some idea. Link to comment Share on other sites More sharing options...
dabus Posted October 22, 2007 Share Posted October 22, 2007 (edited) Uh, look for the helpfile, it's called support-switch.htm in the source-dir.Basicly, it's a gui for robocopy (that's Robust File Copy Utility, a nice piece of free software from microsoft) that may help you to create backup-scripts or run it in background.As you can see, there are a lot of options, since it's a kind of server tool for admins. In my company, we use robocopy to backup parts of our file-server. To get you started, the robocopy-gui may be a help.So read the fine manual. Edited October 22, 2007 by dabus Link to comment Share on other sites More sharing options...
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