llewxam Posted December 4, 2009 Share Posted December 4, 2009 I have been annoyed with the slowness (or latency?) of progressbars in Vista and 7 for a while now and can't find a solution. Using dwmapi.dll hasn't helped, and other endless searches and attempts at fixes haven't helped. I even used sliders as an experiment and they can keep up, why not progressbars? Does anyone have a suggestion on how to make Vista/7 keep up like XP? This lag is killing me!!! ggrrrrrr Also, in the included script, it seems like any time a file hits roughly the 100MB mark there is a stutter which causes the GUI to seemingly twitch or move slightly, and then all of the controls hang until the file has finished copying. Any insights there?? Sorry my example script is so huge..... and thanks for any suggestions in to these issues!!! Ian expandcollapse popup#include <WindowsConstants.au3> ;needed for $WS_EX_ACCEPTFILES, $DT_END_ELLIPSIS #include <EditConstants.au3> ;needed for $ES_READONLY #include <GUIConstantsEx.au3> ;needed for $GUI_DROPACCEPTED, $GUI_HIDE, $GUI_EVENT_CLOSE, $GUI_SHOW, $GUI_UNCHECKED #include <String.au3> ;needed for _StringAddThousandsSep $main=GUICreate("Sync 2 Build 4",550,400,1,1,-1,$WS_EX_ACCEPTFILES) $instructions=GUICtrlCreateLabel("Browse left, type path, or drag and drop",60,5,300,20) GUICtrlCreateLabel("Total Files",400,5,100,20) $totalfileslabel=GUICtrlCreateInput("",400,25,100,20,$ES_READONLY) GUICtrlCreateLabel("Total Size",400,45,100,20) $totalsizelabel=GUICtrlCreateInput("",400,65,100,20,$ES_READONLY) $sourcebtn=GUICtrlCreateButton("Source",5,25,50,20) $targetbtn=GUICtrlCreateButton("Target",5,65,50,20) $addbtn=GUICtrlCreateButton("Add",315,65,50,20) $startbtn=GUICtrlCreateButton("START",485,135,60,20) $sourceinput=GUICtrlCreateInput("",60,25,250,20) $targetinput=GUICtrlCreateInput("",60,65,250,20) $job=GUICtrlCreateList("",5,160,540,215,$ES_READONLY) GUICtrlSetState($sourceinput,$GUI_DROPACCEPTED) GUICtrlSetState($targetinput,$GUI_DROPACCEPTED) GUICtrlSetState($startbtn,$GUI_HIDE) GUISetState(@SW_SHOW,$main) ControlFocus("","",$sourceinput) dim $accelkeys[1][2]=[["{ENTER}",$addbtn]] GUISetAccelerators($accelkeys) Local $callback = DllCallbackRegister('__Progress', 'int', 'uint64;uint64;uint64;uint64;dword;dword;ptr;ptr;str') ;used in.......... Local $ptr = DllCallbackGetPtr($callback) ;............... _CopyWithProgress local $size ;size of task (dir or single file) local $count ;used to help with padding in the listbox local $fill ;the spacing for above local $queue ;the list of what is being copied (all tasks) local $totalfiles ;total number of files to be copied local $totalsize ;total byte count of files local $donesofar ;total bytes copied so far local $bytes ;used as placeholder in __Progress local $failedfiles ;string of failed copies local $failed ;count of failures Do $msg=GUIGetMsg() if $msg=$GUI_EVENT_CLOSE then Exit if $msg=$sourcebtn then GUICtrlSetData($sourceinput,FileSelectFolder("Select a folder","")) if $msg=$targetbtn then GUICtrlSetData($targetinput,FileSelectFolder("Select a folder","",1)) if $msg=$addbtn Then $source=GUICtrlRead($sourceinput) $target=GUICtrlRead($targetinput) if not FileExists($target) then DirCreate($target) if FileExists($source) and FileExists($target) Then $wait=GUICtrlCreateLabel("Please wait, files are being enumerated",100,100,400,20) If StringInStr(FileGetAttrib($source), "D") > 0 Then $count+=1 for $padding=1 to $count $fill&=" " Next $sourceinfo=DirGetSize($source,1) GUICtrlSetData($job,$source&" -> "&$target) GUICtrlSetData($job,"("&_StringAddThousandsSep($sourceinfo[1])&" files "&_StringAddThousandsSep(round($sourceinfo[0]/1000000,2))&"MB)") GUICtrlSetData($job,$fill) $size+=$sourceinfo[0] $totalfiles+=$sourceinfo[1] $totalsize+=$sourceinfo[0] $queue&=$source&chr(1)&$target&chr(1)&"D"&chr(1) GUICtrlSetData($sourceinput,"") GUICtrlSetData($targetinput,"") GUICtrlSetData($totalfileslabel,_StringAddThousandsSep($totalfiles)) GUICtrlSetData($totalsizelabel,_StringAddThousandsSep(round($totalsize/1000000,2))&"MB") GUICtrlDelete($wait) ControlFocus("","",$sourceinput) GUICtrlSetState($startbtn,$GUI_SHOW) Else $count+=1 for $padding=1 to $count $fill&=" " Next $sourceinfo=FileGetSize($source) GUICtrlSetData($job,$source&" -> "&$target) GUICtrlSetData($job,"(1 file "&_StringAddThousandsSep(round($sourceinfo/1000000,2))&"MB)") GUICtrlSetData($job,$fill) $size+=$sourceinfo $totalfiles+=1 $totalsize+=$sourceinfo $queue&=$source&chr(1)&$target&chr(1)&"F"&chr(1) GUICtrlSetData($sourceinput,"") GUICtrlSetData($targetinput,"") GUICtrlSetData($totalfileslabel,_StringAddThousandsSep($totalfiles)) GUICtrlSetData($totalsizelabel,_StringAddThousandsSep(round($totalsize/1000000,2))&"MB") GUICtrlDelete($wait) ControlFocus("","",$sourceinput) GUICtrlSetState($startbtn,$GUI_SHOW) EndIf Else msgbox(0,"Error","Please check your source and target paths") EndIf EndIf ;end $addbtn if $msg=$startbtn Then $display=TimerInit() $howlong=TimerInit() GUICtrlDelete($startbtn) GUICtrlDelete($instructions) ControlDisable("","",$sourcebtn) ControlDisable("","",$targetbtn) ControlDisable("","",$addbtn) ControlDisable("","",$startbtn) ControlDisable("","",$sourceinput) ControlDisable("","",$targetinput) ControlDisable("","",$job) $fileslide=GUICtrlCreateProgress(5,375,265,20) $totalslide=GUICtrlCreateProgress(280,375,265,20) $stop=GUICtrlCreateCheckbox("STOP",495,135,60,20) $showfilename=GUICtrlCreateLabel("",10,100,530,20,$DT_END_ELLIPSIS) GUICtrlCreateLabel("Overall progress - ",10,125,430,20) $showtotalprog=GUICtrlCreateLabel("",96,125,230,20) $breaksources=StringSplit($queue,chr(1)) for $doit=1 to ($breaksources[0]-1) step 3 if $breaksources[$doit+2]="D" then $basedir=$breaksources[$doit] $target=$breaksources[$doit+1] $baselen = StringLen($basedir) theheart($basedir) EndIf if $breaksources[$doit+2]="F" then $source=$breaksources[$doit] $target=$breaksources[$doit+1] $name=StringTrimLeft($source,StringInStr($source,"\",0,-1)) $copied = _CopyWithProgress($source,$target&"\"&$name) if $copied=0 then $failed+=1 $failedfiles&=$source&chr(2) $lastbyte=0 $bytes=0 EndIf EndIf Next GUICtrlSetData($showfilename,"") $totaltimetorun=TimerDiff($howlong) $minutes=round($totaltimetorun/60000,2) if $failed=0 then msgbox(0,"Finished in "&$minutes&" minutes","Finished with no errors") if $failed<>0 then $yesorno=msgbox(4,"Finished in "&$minutes&" minutes","Finished with "&$failed&" errors, do you want to see the failed files?") if $yesorno=6 then $failedwindow=GUICreate("Failed Files",@DesktopWidth,300) ;to display the failed files $failedlist=GUICtrlCreateList("",5,5,@DesktopWidth-10,290) ;to display the failed files GUISetState(@sw_show,$failedwindow) ;done setting up GUI StringTrimRight($failedfiles,1) ;take off the trailing delimeter $failedarray=StringSplit($failedfiles,chr(2)) ;break up the list of failed files for $show=1 to $failedarray[0]-1 GUICtrlSetData($failedlist,$failedarray[$show]) ;list the failed files Next Do $msg=GUIGetMsg() if $msg=$GUI_EVENT_CLOSE then exit ;when the failed window is closed, quit the program until 1=2 EndIf EndIf Exit EndIf ;end $startbtn until 1=2 Func theheart($basedir) While GUICtrlRead($stop) == 1 ;look for the pause button $quit=msgbox(36,"Paused","Quit Now?") if $quit=6 then exit ;yes if $quit=7 then GUICtrlSetState($stop,$GUI_UNCHECKED) ;no, so uuncheck the box WEnd $basesearch = FileFindFirstFile($basedir & "\*.*") If $basesearch == -1 Then Return 0 ; specified folder is empty! While @error <> 1 $basefile = FileFindNextFile($basesearch) ; skip these If $basefile == "." Or $basefile == ".." Or $basefile == "" Then ContinueLoop EndIf ; if it's a dir then call this function again (nesting the function is clever ;) $formattedfile = $basedir & "\" & $basefile If StringInStr(FileGetAttrib($formattedfile), "D") > 0 Then theheart($formattedfile) Else ; Files we need to deal with $dest=StringTrimLeft($formattedfile,$baselen) While GUICtrlRead($stop) == 1 ;look for the pause button $quit=msgbox(36,"Paused","Quit Now?") if $quit=6 then exit ;yes if $quit=7 then GUICtrlSetState($stop,$GUI_UNCHECKED) ;no, so uuncheck the box WEnd GUICtrlSetData($showfilename,$formattedfile);&" - "&$BytesTransferred / $FileSize * 100&"%") if not FileExists($target&$dest) then $copied = _CopyWithProgress($formattedfile,$target&"\"&$dest) if $copied=0 then $failed+=1 $failedfiles&=$formattedfile&chr(2) EndIf Else $donesofar+=FileGetSize($formattedfile) GUICtrlSetData($showtotalprog,round($donesofar / $size * 100,4)&"%") EndIf $lastbyte=0 $bytes=0 endif WEnd FileClose($basesearch) Return 1 EndFunc ;end theheart Func _CopyWithProgress($inSource, $inDest) ; Function to copy a file showing a realtime progress bar ; ; By Paul Niven (NiVZ) ; ; 05/11/2008 ; ; Parameters: ; ; $inSource - Full path to source file ; $inDest - Full path to destination file (structure will be created if it does not exist ; ; Returns 0 if copy is successful and 1 if it fails ; ; ; Updates: ; ; 06/11/2008 - Now shows SOURCE and DEST on seperate lines while copying ; - Now uses Kernal32 and DllCallBackRegister to provide faster copying ; Kernal32 and DllCallBackRegister taken from _MultiFileCopy.au3 ; See: http://www.autoit.de/index.php?page=Thread&postID=58875 $DestDir = StringLeft($inDest, StringInStr($inDest, "\", "", -1)) If Not FileExists($DestDir) Then DirCreate($DestDir) $ret = DllCall('kernel32.dll', 'int', 'CopyFileExA', 'str', $inSource, 'str', $inDest, 'ptr', $ptr, 'str', '', 'int', 0, 'int', 0) If $ret[0] <> 0 Then ; Success Return 1 Else ; Fail Return 0 EndIf EndFunc Func __Progress($FileSize, $BytesTransferred, $StreamSize, $StreamBytesTransferred, $dwStreamNumber, $dwCallbackReason, $hSourceFile, $hDestinationFile, $lpData) $lastbyte=$bytes $bytes=$BytesTransferred $bytediff=$bytes-$lastbyte $donesofar+=$bytediff GUICtrlSetData($showtotalprog,round($donesofar / $size * 100,4)&"%") GUICtrlSetData($totalslide,$donesofar / $size * 100) GUICtrlSetData($fileslide,$BytesTransferred / $FileSize * 100) EndFunc My projects: IP Scanner - Multi-threaded ping tool to scan your available networks for used and available IP addresses, shows ping times, resolves IPs in to host names, and allows individual IPs to be pinged. INFSniff - Great technicians tool - a tool which scans DriverPacks archives for INF files and parses out the HWIDs to a database file, and rapidly scans the local machine's HWIDs, searches the database for matches, and installs them. PPK3 (Persistent Process Killer V3) - Another for the techs - suppress running processes that you need to keep away, helpful when fighting spyware/viruses. Sync Tool - Folder sync tool with lots of real time information and several checking methods. USMT Front End - Front End for Microsoft's User State Migration Tool, including all files needed for USMT 3.01 and 4.01, 32 bit and 64 bit versions. Audit Tool - Computer audit tool to gather vital hardware, Windows, and Office information for IT managers and field techs. Capabilities include creating a customized site agent. CSV Viewer - Displays CSV files with automatic column sizing and font selection. Lines can also be copied to the clipboard for data extraction. MyDirStat - Lists number and size of files on a drive or specified path, allows for deletion within the app. 2048 Game - My version of 2048, fun tile game. Juice Lab - Ecigarette liquid making calculator. Data Protector - Secure notes to save sensitive information. VHD Footer - Add a footer to a forensic hard drive image to allow it to be mounted or used as a virtual machine hard drive. Find in File - Searches files containing a specified phrase. Link to comment Share on other sites More sharing options...
shovetech Posted December 18, 2009 Share Posted December 18, 2009 I wrote a progress bar for a single file copy here. All it uses is the native windows copy command (any version), and displays a progress bar with speed, bytes transfered, and estimated time remaining. http://www.autoitscript.com/forum/index.php?showtopic=15384&st=0&p=755467&#entry755467 Link to comment Share on other sites More sharing options...
danielkza Posted December 19, 2009 Share Posted December 19, 2009 First of all, your example script is indeed huge, and very hard to understand. It seems just to copy files from some folders to other folders, but it's hard to figure out because everything is just piled up with no organization whatsoever. I tested it anyway. It copied 300MB of music from one folder to another with no hiccups, and the progress bars behaved as expected. I'm running Windows 7 RC1, which leads me to believe your problem is not what you believed it to be. Link to comment Share on other sites More sharing options...
shovetech Posted December 19, 2009 Share Posted December 19, 2009 First of all, your example script is indeed huge, and very hard to understand. It seems just to copy files from some folders to other folders, but it's hard to figure out because everything is just piled up with no organization whatsoever.I tested it anyway. It copied 300MB of music from one folder to another with no hiccups, and the progress bars behaved as expected. I'm running Windows 7 RC1, which leads me to believe your problem is not what you believed it to be.Sorry, which script were you referring to? If it's mine above, what about it should be changed? Link to comment Share on other sites More sharing options...
llewxam Posted December 19, 2009 Author Share Posted December 19, 2009 (edited) Sorry, which script were you referring to? If it's mine above, what about it should be changed?LOL, too many funny things "all piled up" here! danielkza was referring to my script which I think is very easy to understand and is well organized, but it is very large and I know it is overwhelming to look at that much of someone else's code and feel comfortable. I know I get lost sometimes!! We all have our own styles, I usually choose to not go the "function for everything" model and code more linearly. Also, the point of my complaint was that it stutters on a SINGLE large file, not hundreds of megs of tiny ones, have it transfer something at least a few hundred MB and you will see it.Back to the point though, as luck has it I saw your code late last night shovetech and played around with it a lot, it is excellent and is JUST what I needed! Right now I am kinda in between merging your code and mine, and I really am looking forward to getting it completed. I have been loosing my mind trying to get the _CopyWithProgress that has been floating around to work without stuttering, but now, I DON'T HAVE TO!! Hopefully more people will migrate towards yours who have been having issues.Thanks for posting the code in the first place, and for giving a crap enough to point me in the direction of your post.Ian Edited December 19, 2009 by llewxam My projects: IP Scanner - Multi-threaded ping tool to scan your available networks for used and available IP addresses, shows ping times, resolves IPs in to host names, and allows individual IPs to be pinged. INFSniff - Great technicians tool - a tool which scans DriverPacks archives for INF files and parses out the HWIDs to a database file, and rapidly scans the local machine's HWIDs, searches the database for matches, and installs them. PPK3 (Persistent Process Killer V3) - Another for the techs - suppress running processes that you need to keep away, helpful when fighting spyware/viruses. Sync Tool - Folder sync tool with lots of real time information and several checking methods. USMT Front End - Front End for Microsoft's User State Migration Tool, including all files needed for USMT 3.01 and 4.01, 32 bit and 64 bit versions. Audit Tool - Computer audit tool to gather vital hardware, Windows, and Office information for IT managers and field techs. Capabilities include creating a customized site agent. CSV Viewer - Displays CSV files with automatic column sizing and font selection. Lines can also be copied to the clipboard for data extraction. MyDirStat - Lists number and size of files on a drive or specified path, allows for deletion within the app. 2048 Game - My version of 2048, fun tile game. Juice Lab - Ecigarette liquid making calculator. Data Protector - Secure notes to save sensitive information. VHD Footer - Add a footer to a forensic hard drive image to allow it to be mounted or used as a virtual machine hard drive. Find in File - Searches files containing a specified phrase. Link to comment Share on other sites More sharing options...
danielkza Posted December 19, 2009 Share Posted December 19, 2009 I was referring to llewxam's script. @llewxam: It may seem organized to you, but the fact that logic is not compartmentalized in any way (having a function that does everything does not help). Also, you create and delete windows and controls often, and those are hard to keep track of, specially when you are not the one writing the code. If this is a script you plan on using as-is, there is no problem in keeping it like that. But trust me, if you plan on writing any larger projects, having reusable code, that keeps track of its resources and frees you of caring about inner workings as much as possible will go a long way on improving the final product, and keeping you sane. Link to comment Share on other sites More sharing options...
shovetech Posted December 19, 2009 Share Posted December 19, 2009 LOL, too many funny things "all piled up" here! danielkza was referring to my script which I think is very easy to understand and is well organized, but it is very large and I know it is overwhelming to look at that much of someone else's code and feel comfortable. I know I get lost sometimes!! We all have our own styles, I usually choose to not go the "function for everything" model and code more linearly. Also, the point of my complaint was that it stutters on a SINGLE large file, not hundreds of megs of tiny ones, have it transfer something at least a few hundred MB and you will see it.Back to the point though, as luck has it I saw your code late last night shovetech and played around with it a lot, it is excellent and is JUST what I needed! Right now I am kinda in between merging your code and mine, and I really am looking forward to getting it completed. I have been loosing my mind trying to get the _CopyWithProgress that has been floating around to work without stuttering, but now, I DON'T HAVE TO!! Hopefully more people will migrate towards yours who have been having issues.Thanks for posting the code in the first place, and for giving a crap enough to point me in the direction of your post.IanMy code is not good by any means though. As it stands, it can only copy a single file. I'm working on having it copy multiple files (directories, etc.), using only the copy command. I was thinking about using xcopy, but wanted to keep the depencancy list minimal.Anyway, looking forward to seeing your code. (That is until AutoIT internal devs create a function called '_CopyWithProgress' LOL!) Link to comment Share on other sites More sharing options...
danielkza Posted December 20, 2009 Share Posted December 20, 2009 @shovetech: What DLL exactly are you missing in WinPE? It can't be shell32.dll, because no graphical program would work without it, and I doubt it is shlwapi.dll, because it seems to be used in lots of places as well (including Windows Explorer IIRC). Link to comment Share on other sites More sharing options...
llewxam Posted December 20, 2009 Author Share Posted December 20, 2009 My code is not good by any means though. As it stands, it can only copy a single file. I'm working on having it copy multiple files (directories, etc.), using only the copy command. I was thinking about using xcopy, but wanted to keep the depencancy list minimal. Anyway, looking forward to seeing your code. (That is until AutoIT internal devs create a function called '_CopyWithProgress' LOL!) No time to work on this today so far until now, I may try to get a few other things organized first though before continuing. I was trying to copy a directory (with subdirectories) with the original file recursion routine I have used for an eternity that I didn't write, but for some reason it isn't working well with that routine, something isn't playing nice and the app just stops before all of the files have been copied. Of course, if I hadn't commented or ripped out your error checking, maybe I'd have a clue as to what is happening!! hahahahhaha. I'll post it so you can see, but be warned - I have hacked out a LOT of your original code, and what I have here doesn't work well, at all! I am going to try putting together my own recursion routine that I think will work well with what you have, and hopefully that will have a better result. Here it is, as-is, in all it's broken glory! expandcollapse popup; Copies a file using the native Windows copy command, but ; displays statistics while copying. ; Works especially good in a WinPE environment ; ; Version: 1.0.0 ; ; Author: Doug Shove ; #include <GUIConstants.au3> #include <GUIConstantsEx.au3> #include <ProgressConstants.au3> #include <ButtonConstants.au3> #Include <GuiButton.au3> #Include <File.au3> Opt("GUICoordMode", 0) Opt("GUIOnEventMode", 1) Opt("MustDeclareVars", 1) Global $invalidChars = "/ : * ? < > | " & chr(34) Global $forceoverwrite = 0 Global $showcopytime = 0 Global $title = "Copying files..." Global $source Global $destination Global $procstats Global $filedrive Global $filepath Global $filename Global $fileext Global $copyfiletime ; Global GUI controls Global $guiwin, $cancelbtn, $progressbar, $msg, $index, $lblbytes, $source, $basesearch, $basefile, $formattedfile, $basedir, $target, $baselen Global $lbltransfer, $lblspin, $lblfiles, $lbltime Global $spin = "|" Global $progresstime = TimerInit() Global $progresssubstring = "" Global $pid = 0 Global $sourcesize = 0 Global $destinationsize = 0 Global $copystatus = 1 Global $statusrefresh = 1000 $guiwin = GUICreate($title, 300, 130) $lblbytes = GUICtrlCreateLabel("Preparing...", 5, 5, 290) $progressbar = GUICtrlCreateProgress(-1, 20, 290, 20, $PBS_SMOOTH) $lblfiles = GUICtrlCreateLabel("Source: " & $source & @LF & "Destination: " & $destination , -1, 21, 290, 26) $lbltransfer = GUICtrlCreateLabel("", -1, 27, 290, 13) $lbltime = GUICtrlCreateLabel("", -1, 14, 290, 13) $cancelbtn = GUICtrlCreateButton("Cancel", 230, 15, 60) GUICtrlSetOnEvent($cancelbtn, "cancelop") GUISetOnEvent($GUI_EVENT_CLOSE, "cancelop") GUISetState(@SW_SHOW) ; Start copying file $basedir="c:\users\me\desktop\inventory" $baselen = StringLen($basedir) $target="d:\new" theheart($basedir) Exit Func killproc($pid) ; kills a process While (ProcessExists($pid)) ProcessClose($pid) WEnd EndFunc Func cancelop() ; If copystatus = 0 (not copying...) If ($copystatus = 0) Then GUISetState(@SW_HIDE) Exit EndIf If (MsgBox(4 + 32 + 256, "Copy File Progress", "Are you sure you want to cancel file copy?") = 6) Then GUICtrlSetState($cancelbtn, $GUI_DISABLE) WinSetTitle($guiwin, "", $title & " canceling...") GUICtrlSetData($lblbytes, "Canceling.....") GUICtrlSetData($lbltransfer, "") GUICtrlSetData($lbltime, "") killproc($pid) GUICtrlSetData($lblbytes, "Removing " & $destination & " .....") If (FileExists($destination)) Then FileDelete($destination) EndIf Exit EndIf EndFunc Func copyFile($source, $destination) Dim $sourceprefix = 0 Dim $sourcesuffix = "" getByteSuffix($sourcesize, $sourceprefix, $sourcesuffix) Dim $bytestransfered = 0 Dim $transferspeed = 0 Dim $transfersize = 0 Dim $timeremaining = 0 Dim $progress = 0 Dim $maxbytes = 0 Dim $minbytes = 0 Dim $index = 1 Dim $starttime = TimerInit() $pid = Run(@ComSpec & " /c copy /y " & chr(34) & $source & chr(34) & " " & Chr(34) & $destination & Chr(34), @ScriptDir, @SW_HIDE) If ($pid = 0) Then ;~ MsgBox(16, "Error", "Error running copy command") ;~ Exit EndIf While (ProcessExists($pid)) $procstats = ProcessGetStats($pid, 1) If (IsArray($procstats) And UBound($procstats) > 4) Then If (Int(timerdiff($starttime)) > $statusrefresh) Then $transferspeed = Int($procstats[4] / (TimerDiff($copyfiletime) / 1000)) If ($transferspeed > 0) Then $timeremaining = (($sourcesize - $procstats[4]) / $transferspeed) EndIf $transfersize = $procstats[4] $starttime = TimerInit() $progresstime = TimerInit() EndIf $destinationsize = $procstats[4] If ($destinationsize > $sourcesize) Then $destinationsize = $sourcesize EndIf $progress = $destinationsize / $sourcesize * 100 progressUpdate($progress, $sourcesize, $destinationsize, $transferspeed, $timeremaining) EndIf Sleep(100) $index = ($index + 1) WEnd ; After copy finished, display destination file size $destinationsize = FileGetSize($destination) $progress = Int(($destinationsize / $sourcesize) * 100) $timeremaining = 0 $transferspeed = 0 $spin = "" progressUpdate($progress, $sourcesize, $destinationsize, $transferspeed, $timeremaining) ; If destination file doesn't exist, display error If (FileExists($destination) = 0) Then ;~ MsgBox(16, "Error", "Could not create file " & $destination) ;~ Exit EndIf ; Compare source file size and destination file size If ($sourcesize <> $destinationsize) Then ;~ MsgBox(16, "Error", "Source and destination file sizes are different. Could not copy.") ;~ FileDelete($destination) ;~ Exit EndIf EndFunc Func progressUpdate($progress, $sourcesize, $destsize, $transferspeed, $timeremaining) ; Don't let progress bar above 100% If ($progress > 100) Then $progress = 100 EndIf ; Display spin If (StringLen($spin) > 50) Then $spin = StringRight($spin, 1) Switch StringRight($spin, 1) Case "|" $spin = StringReplace($spin, "|", "/", 1, 2) Case "/" $spin = StringReplace($spin, "/", "-", 1, 2) Case "-" $spin = StringReplace($spin, "-", "\", 1, 2) Case "\" $spin = StringReplace($spin, "\", ".", 1, 2) & ".|" EndSwitch Local $sourceprefix = 0 Local $sourcesuffix = "" getByteSuffix($sourcesize, $sourceprefix, $sourcesuffix) Local $byteprefix = 0 Local $bytesuffix = "" getByteSuffix($destsize, $byteprefix, $bytesuffix) Local $speedprefix = 0 Local $speedsuffix = "" Local $speedstring = "" Local $timeremainstring = "" If ($destsize > 0) Then ; display current speed If ($transferspeed > 0) Then getByteSuffix($transferspeed, $speedprefix, $speedsuffix) If (Int($speedprefix) > 0) Then $speedstring = "Speed: " & Int($speedprefix) & " " & $speedsuffix & "/s" EndIf EndIf $progresssubstring = $speedstring ; display time remaining If (Int($timeremaining) > 0) Then $timeremainstring = " - Remaining: " & getTime($timeremaining) EndIf GUICtrlSetData($progressbar, $progress) GUICtrlSetData($lblbytes, Int($byteprefix) & " " & $bytesuffix & " / " & Int($sourceprefix) & " " & $sourcesuffix & " " & $spin) GUICtrlSetData($lbltransfer, $progresssubstring) GUICtrlSetData($lbltime, "Elapsed: " & getTime(timerdiff($copyfiletime) / 1000) & $timeremainstring) WinSetTitle($guiwin, "", $title & " " & $progress & " %") EndIf EndFunc Func getTime($secs) ; Take time in seconds and convert to hours, mins, seconds, etc... Local $seconds = $secs Local $mins = 0 Local $hours = 0 Local $days = 0 Local $weeks = 0 Local $months = 0 Local $timestring = Int($seconds) & " secs" If ($seconds > 60) Then $mins = Int($seconds / 60) $seconds = Int($seconds - ($mins * 60)) If ($seconds <= 0) Then $timestring = $mins & " mins" Else $timestring = $mins & " mins " & $seconds & " secs" EndIf If ($mins > 60) Then $hours = Int($mins / 60) $mins = Int($mins - ($hours * 60)) If ($mins <= 0) Then $timestring = $hours & " hours" Else $timestring = $hours & " hours " & $mins & " mins" EndIf If ($hours > 24) Then $days = Int($hours / 24) $hours = Int($hours - ($days * 24)) If ($hours <= 0) Then $timestring = $days & " days" Else $timestring = $days & " days " & $hours & " hours" EndIf If ($days > 7) Then $weeks = Int($days / 7) $days = Int($days - ($weeks * 7)) If ($days <= 0) Then $timestring = $weeks & " weeks" Else $timestring = $weeks & " weeks " & $days & " days" EndIf If ($weeks > 4) Then $months = Int($weeks / 4) $weeks = Int($weeks - ($months * 4)) If ($weeks <= 0) Then $timestring = $months & " months" Else $timestring = $months & " months " & $weeks & " weeks" EndIf EndIf EndIf EndIf EndIf EndIf Return $timestring EndFunc Func getByteSuffix ($bytes, ByRef $byteprefix, ByRef $bytesuffix) $byteprefix = $bytes $bytesuffix = "bytes" If ($byteprefix > 1024) Then $byteprefix = ($byteprefix / 1024) $bytesuffix = "KB" If ($byteprefix > 1024) Then $byteprefix = ($byteprefix / 1024) $bytesuffix = "MB" If ($byteprefix > 1024) Then $byteprefix = ($byteprefix / 1024) $bytesuffix = "GB" If ($byteprefix > 1024) Then $byteprefix = ($byteprefix / 1024) $bytesuffix = "TB" If ($byteprefix > 1024) Then $byteprefix = ($byteprefix / 1024) $bytesuffix = "PB" EndIf EndIf EndIf EndIf EndIf EndFunc ;~ Func validPath ($input) ;~ ; search through invalidChars against input ;~ Local $invalidCharArray = StringSplit($invalidChars, " ") ;~ For $x = 1 to $invalidCharArray[0] ;~ If (StringInStr($input, $invalidCharArray[$x])) Then ;~ Return 0 ;~ EndIf ;~ Next ;~ Return 1 ;~ EndFunc func theheart($basedir) $basesearch = fileFindFirstFile($basedir & "\*.*") if $basesearch==-1 then return 0 ; specified folder is empty! while @error<>1 $basefile = fileFindNextFile($basesearch) ; skip these if $basefile=="." or $basefile==".." or $basefile=="" then continueLoop endIf ; if it's a dir then call this function again (nesting the function is clever ;) $formattedfile=$basedir&"\"&$basefile if stringInStr(fileGetAttrib($formattedfile), "D") > 0 then theheart($formattedfile) else ; Files we need to deal with $source = $formattedfile $sourcesize = FileGetSize($source) $destination=$target&StringTrimLeft($formattedfile,$baselen) GUICtrlSetData($lblfiles,"Source: " & $source & @LF & "Destination: " & $destination) if not FileExists($destination) then ; Check for illegal characters in destination _PathSplit($destination, $filedrive, $filepath, $filename, $fileext) ;~ If (validPath($filepath) = 0 Or _ ;~ validPath($filename) = 0 Or _ ;~ validPath($fileext) = 0) Then ;~ MsgBox (16, "Error", "Destination file name invalid. File name cannot contain: " & @LF & $invalidChars) ;~ Exit ;~ EndIf ; if destination directory doesn't exist, create it If ($filedrive <> "" And $filepath <> "" And _ FileExists($filedrive & $filepath) = 0) Then DirCreate($filedrive & $filepath) If (FileExists($filedrive & $filepath) = 0) Then MsgBox(16, "Error", "Could not create " & $filedrive & $filepath & ". File copy failed") ;~ Exit EndIf EndIf $copyfiletime = TimerInit() copyFile($source, $destination) $copystatus = 0 If ($showcopytime = 1) Then _GUICtrlButton_SetText ($cancelbtn, "Close") while (1) Sleep (1000) WEnd EndIf EndIf endIf wEnd fileClose($basesearch) return 1 endFunc My projects: IP Scanner - Multi-threaded ping tool to scan your available networks for used and available IP addresses, shows ping times, resolves IPs in to host names, and allows individual IPs to be pinged. INFSniff - Great technicians tool - a tool which scans DriverPacks archives for INF files and parses out the HWIDs to a database file, and rapidly scans the local machine's HWIDs, searches the database for matches, and installs them. PPK3 (Persistent Process Killer V3) - Another for the techs - suppress running processes that you need to keep away, helpful when fighting spyware/viruses. Sync Tool - Folder sync tool with lots of real time information and several checking methods. USMT Front End - Front End for Microsoft's User State Migration Tool, including all files needed for USMT 3.01 and 4.01, 32 bit and 64 bit versions. Audit Tool - Computer audit tool to gather vital hardware, Windows, and Office information for IT managers and field techs. Capabilities include creating a customized site agent. CSV Viewer - Displays CSV files with automatic column sizing and font selection. Lines can also be copied to the clipboard for data extraction. MyDirStat - Lists number and size of files on a drive or specified path, allows for deletion within the app. 2048 Game - My version of 2048, fun tile game. Juice Lab - Ecigarette liquid making calculator. Data Protector - Secure notes to save sensitive information. VHD Footer - Add a footer to a forensic hard drive image to allow it to be mounted or used as a virtual machine hard drive. Find in File - Searches files containing a specified phrase. Link to comment Share on other sites More sharing options...
llewxam Posted December 20, 2009 Author Share Posted December 20, 2009 Dunno shove, I just wrote a file recursion script of my own and the app still died before it was done. Doubting myself I found another recursion routing and used it, same thing. I thought it was due to a huge file since that is when it died, but after I moved them elsewhere I am still having the same issue. BTW, I like your sizing method but my file was 1.36GB and your GUI just showed it as 1GB, kinda odd. Oh, and I broke the INT on the titlebar, my bad, but didn't fix it. Anyway, here is what I did tonight, and maybe the post I did above would work just fine but the error is somewhere else (kinda seems likely) expandcollapse popup; Copies a file using the native Windows copy command, but ; displays statistics while copying. ; Works especially good in a WinPE environment ; ; Version: 1.0.0 ; ; Author: Doug Shove ; #include <GUIConstants.au3> #include <GUIConstantsEx.au3> #include <ProgressConstants.au3> #include <ButtonConstants.au3> #Include <GuiButton.au3> #Include <File.au3> Opt("GUICoordMode", 0) Opt("GUIOnEventMode", 1) Opt("MustDeclareVars", 1) Global $invalidChars = "/ : * ? < > | " & chr(34) Global $forceoverwrite = 0 Global $showcopytime = 0 Global $title = "Copying files..." Global $source Global $destination Global $procstats Global $filedrive Global $filepath Global $filename Global $fileext Global $copyfiletime ; Global GUI controls Global $guiwin, $cancelbtn, $progressbar, $msg, $index, $lblbytes, $source, $basesearch, $basefile, $formattedfile, $basedir, $target, $baselen, $search, $next, $sourcelen Global $lbltransfer, $lblspin, $lblfiles, $lbltime Global $spin = "|" Global $progresstime = TimerInit() Global $progresssubstring = "" Global $pid = 0 Global $sourcesize = 0 Global $destinationsize = 0 Global $copystatus = 1 Global $statusrefresh = 1000 $guiwin = GUICreate($title, 300, 130) $lblbytes = GUICtrlCreateLabel("Preparing...", 5, 5, 290) $progressbar = GUICtrlCreateProgress(-1, 20, 290, 20, $PBS_SMOOTH) $lblfiles = GUICtrlCreateLabel("Source: " & $source & @LF & "Destination: " & $destination , -1, 21, 290, 26) $lbltransfer = GUICtrlCreateLabel("", -1, 27, 290, 13) $lbltime = GUICtrlCreateLabel("", -1, 14, 290, 13) $cancelbtn = GUICtrlCreateButton("Cancel", 230, 15, 60) GUICtrlSetOnEvent($cancelbtn, "cancelop") GUISetOnEvent($GUI_EVENT_CLOSE, "cancelop") GUISetState(@SW_SHOW) ; Start copying file Global $source = "c:\users\me\desktop" $sourcelen = StringLen($source) Global $target = "d:\new" Global $sourcesize RecursiveFileSearch($source) Exit Func killproc($pid) ; kills a process While (ProcessExists($pid)) ProcessClose($pid) WEnd EndFunc Func cancelop() ; If copystatus = 0 (not copying...) If ($copystatus = 0) Then GUISetState(@SW_HIDE) Exit EndIf If (MsgBox(4 + 32 + 256, "Copy File Progress", "Are you sure you want to cancel file copy?") = 6) Then GUICtrlSetState($cancelbtn, $GUI_DISABLE) WinSetTitle($guiwin, "", $title & " canceling...") GUICtrlSetData($lblbytes, "Canceling.....") GUICtrlSetData($lbltransfer, "") GUICtrlSetData($lbltime, "") killproc($pid) GUICtrlSetData($lblbytes, "Removing " & $destination & " .....") If (FileExists($destination)) Then FileDelete($destination) EndIf Exit EndIf EndFunc Func copyFile($source, $destination) Dim $sourceprefix = 0 Dim $sourcesuffix = "" getByteSuffix($sourcesize, $sourceprefix, $sourcesuffix) Dim $bytestransfered = 0 Dim $transferspeed = 0 Dim $transfersize = 0 Dim $timeremaining = 0 Dim $progress = 0 Dim $maxbytes = 0 Dim $minbytes = 0 Dim $index = 1 Dim $starttime = TimerInit() $pid = Run(@ComSpec & " /c copy /y " & chr(34) & $source & chr(34) & " " & Chr(34) & $destination & Chr(34), @ScriptDir, @SW_HIDE) If ($pid = 0) Then ;~ MsgBox(16, "Error", "Error running copy command") ;~ Exit EndIf While (ProcessExists($pid)) $procstats = ProcessGetStats($pid, 1) If (IsArray($procstats) And UBound($procstats) > 4) Then If (Int(timerdiff($starttime)) > $statusrefresh) Then $transferspeed = Int($procstats[4] / (TimerDiff($copyfiletime) / 1000)) If ($transferspeed > 0) Then $timeremaining = (($sourcesize - $procstats[4]) / $transferspeed) EndIf $transfersize = $procstats[4] $starttime = TimerInit() $progresstime = TimerInit() EndIf $destinationsize = $procstats[4] If ($destinationsize > $sourcesize) Then $destinationsize = $sourcesize EndIf $progress = $destinationsize / $sourcesize * 100 progressUpdate($progress, $sourcesize, $destinationsize, $transferspeed, $timeremaining) EndIf Sleep(100) $index = ($index + 1) WEnd ; After copy finished, display destination file size $destinationsize = FileGetSize($destination) $progress = Int(($destinationsize / $sourcesize) * 100) $timeremaining = 0 $transferspeed = 0 $spin = "" progressUpdate($progress, $sourcesize, $destinationsize, $transferspeed, $timeremaining) ; If destination file doesn't exist, display error If (FileExists($destination) = 0) Then ;~ MsgBox(16, "Error", "Could not create file " & $destination) ;~ Exit EndIf ; Compare source file size and destination file size If ($sourcesize <> $destinationsize) Then ;~ MsgBox(16, "Error", "Source and destination file sizes are different. Could not copy.") ;~ FileDelete($destination) ;~ Exit EndIf EndFunc Func progressUpdate($progress, $sourcesize, $destsize, $transferspeed, $timeremaining) ; Don't let progress bar above 100% If ($progress > 100) Then $progress = 100 EndIf ; Display spin If (StringLen($spin) > 50) Then $spin = StringRight($spin, 1) Switch StringRight($spin, 1) Case "|" $spin = StringReplace($spin, "|", "/", 1, 2) Case "/" $spin = StringReplace($spin, "/", "-", 1, 2) Case "-" $spin = StringReplace($spin, "-", "\", 1, 2) Case "\" $spin = StringReplace($spin, "\", ".", 1, 2) & ".|" EndSwitch Local $sourceprefix = 0 Local $sourcesuffix = "" getByteSuffix($sourcesize, $sourceprefix, $sourcesuffix) Local $byteprefix = 0 Local $bytesuffix = "" getByteSuffix($destsize, $byteprefix, $bytesuffix) Local $speedprefix = 0 Local $speedsuffix = "" Local $speedstring = "" Local $timeremainstring = "" If ($destsize > 0) Then ; display current speed If ($transferspeed > 0) Then getByteSuffix($transferspeed, $speedprefix, $speedsuffix) If (Int($speedprefix) > 0) Then $speedstring = "Speed: " & Int($speedprefix) & " " & $speedsuffix & "/s" EndIf EndIf $progresssubstring = $speedstring ; display time remaining If (Int($timeremaining) > 0) Then $timeremainstring = " - Remaining: " & getTime($timeremaining) EndIf GUICtrlSetData($progressbar, $progress) GUICtrlSetData($lblbytes, Int($byteprefix) & " " & $bytesuffix & " / " & Int($sourceprefix) & " " & $sourcesuffix & " " & $spin) GUICtrlSetData($lbltransfer, $progresssubstring) GUICtrlSetData($lbltime, "Elapsed: " & getTime(timerdiff($copyfiletime) / 1000) & $timeremainstring) WinSetTitle($guiwin, "", $title & " " & $progress & " %") EndIf EndFunc Func getTime($secs) ; Take time in seconds and convert to hours, mins, seconds, etc... Local $seconds = $secs Local $mins = 0 Local $hours = 0 Local $days = 0 Local $weeks = 0 Local $months = 0 Local $timestring = Int($seconds) & " secs" If ($seconds > 60) Then $mins = Int($seconds / 60) $seconds = Int($seconds - ($mins * 60)) If ($seconds <= 0) Then $timestring = $mins & " mins" Else $timestring = $mins & " mins " & $seconds & " secs" EndIf If ($mins > 60) Then $hours = Int($mins / 60) $mins = Int($mins - ($hours * 60)) If ($mins <= 0) Then $timestring = $hours & " hours" Else $timestring = $hours & " hours " & $mins & " mins" EndIf If ($hours > 24) Then $days = Int($hours / 24) $hours = Int($hours - ($days * 24)) If ($hours <= 0) Then $timestring = $days & " days" Else $timestring = $days & " days " & $hours & " hours" EndIf If ($days > 7) Then $weeks = Int($days / 7) $days = Int($days - ($weeks * 7)) If ($days <= 0) Then $timestring = $weeks & " weeks" Else $timestring = $weeks & " weeks " & $days & " days" EndIf If ($weeks > 4) Then $months = Int($weeks / 4) $weeks = Int($weeks - ($months * 4)) If ($weeks <= 0) Then $timestring = $months & " months" Else $timestring = $months & " months " & $weeks & " weeks" EndIf EndIf EndIf EndIf EndIf EndIf Return $timestring EndFunc Func getByteSuffix ($bytes, ByRef $byteprefix, ByRef $bytesuffix) $byteprefix = $bytes $bytesuffix = "bytes" If ($byteprefix > 1024) Then $byteprefix = ($byteprefix / 1024) $bytesuffix = "KB" If ($byteprefix > 1024) Then $byteprefix = ($byteprefix / 1024) $bytesuffix = "MB" If ($byteprefix > 1024) Then $byteprefix = ($byteprefix / 1024) $bytesuffix = "GB" If ($byteprefix > 1024) Then $byteprefix = ($byteprefix / 1024) $bytesuffix = "TB" If ($byteprefix > 1024) Then $byteprefix = ($byteprefix / 1024) $bytesuffix = "PB" EndIf EndIf EndIf EndIf EndIf EndFunc Func RecursiveFileSearch ($startDir, $depth = 0) If $depth = 0 Then Global $RFSstring = "" $search = FileFindFirstFile($startDir & "\*.*") If @error Then Return ;Search through all files and folders in directory While 1 $next = FileFindNextFile($search) If @error Then ExitLoop ;If folder, recurse If StringInStr(FileGetAttrib($startDir & "\" & $next), "D") Then RecursiveFileSearch ($startDir & "\" & $next, $depth + 1) Else $destination=$target&(StringTrimLeft($startDir&"\"&$next,$sourcelen)) if not FileExists($destination) then _PathSplit($destination, $filedrive, $filepath, $filename, $fileext) ; if destination directory doesn't exist, create it If ($filedrive <> "" And $filepath <> "" And _ FileExists($filedrive & $filepath) = 0) Then DirCreate($filedrive & $filepath) If (FileExists($filedrive & $filepath) = 0) Then MsgBox(16, "Error", "Could not create " & $filedrive & $filepath & ". File copy failed") ;~ Exit EndIf EndIf $sourcesize = FileGetSize($startDir&"\"&$next) GUICtrlSetData($lblfiles,"Source: " & $source & @LF & "Destination: " & $destination) $copyfiletime = TimerInit() copyFile($startDir&"\"&$next, $destination) $copystatus = 0 If ($showcopytime = 1) Then _GUICtrlButton_SetText ($cancelbtn, "Close") while (1) Sleep (1000) WEnd EndIf EndIf EndIf WEnd FileClose($search) If $depth = 0 Then Return EndFunc;==>RecursiveFileSearch Hopefully you can figure out the glitch, I really would be happy to have a better copy w/ progress!!!!! Good luck, let me know Ian My projects: IP Scanner - Multi-threaded ping tool to scan your available networks for used and available IP addresses, shows ping times, resolves IPs in to host names, and allows individual IPs to be pinged. INFSniff - Great technicians tool - a tool which scans DriverPacks archives for INF files and parses out the HWIDs to a database file, and rapidly scans the local machine's HWIDs, searches the database for matches, and installs them. PPK3 (Persistent Process Killer V3) - Another for the techs - suppress running processes that you need to keep away, helpful when fighting spyware/viruses. Sync Tool - Folder sync tool with lots of real time information and several checking methods. USMT Front End - Front End for Microsoft's User State Migration Tool, including all files needed for USMT 3.01 and 4.01, 32 bit and 64 bit versions. Audit Tool - Computer audit tool to gather vital hardware, Windows, and Office information for IT managers and field techs. Capabilities include creating a customized site agent. CSV Viewer - Displays CSV files with automatic column sizing and font selection. Lines can also be copied to the clipboard for data extraction. MyDirStat - Lists number and size of files on a drive or specified path, allows for deletion within the app. 2048 Game - My version of 2048, fun tile game. Juice Lab - Ecigarette liquid making calculator. Data Protector - Secure notes to save sensitive information. VHD Footer - Add a footer to a forensic hard drive image to allow it to be mounted or used as a virtual machine hard drive. Find in File - Searches files containing a specified phrase. Link to comment Share on other sites More sharing options...
danielkza Posted December 20, 2009 Share Posted December 20, 2009 Why don't you guys use SHFileOperation? Link to comment Share on other sites More sharing options...
shovetech Posted December 20, 2009 Share Posted December 20, 2009 Why don't you guys use SHFileOperation?I haven't tried any Micrsoft APIs yet, I just assumed from reading some other posts around the net that people were reporting they were not able to get an explorer-like copy dialog box when using WinPE. This is what prompted me to create my own. As for full installs of XP/Vista/Win7, I'm sure you can do this pretty easy.I've updated my code here a bit. It now supports copying of files or directories as input.As far as the file size (ex. 1.3 GB) showing as 1 GB, this is by design. You can extend this to any number of decimal places you like by editing Func progressUpdate the line: GUICtrlSetData($lblbytes, Int($byteprefix) & " " & $bytesuffix & " / " & Int($sourceprefix) to this: GUICtrlSetData($lblbytes, Round($byteprefix, 3) & " " & $bytesuffix & " / " & Round($sourceprefix,3) Link to comment Share on other sites More sharing options...
llewxam Posted December 21, 2009 Author Share Posted December 21, 2009 Here is another update on my take on your code All I did was transplant a few functions, add a DirCreate to make paths work, and a GetFileSize on the source and destination to add some error correction. I still have much to do (GUIOnEventMode, find a way to do a running tally of overall progress during large transfers, no doubt many more things will come up) but wanted to put it up for you to see. expandcollapse popup#include <EditConstants.au3> ;needed for $ES_READONLY #include <GUIConstantsEx.au3> ;needed for $GUI_DROPACCEPTED, $GUI_HIDE, $GUI_EVENT_CLOSE, $GUI_SHOW, $GUI_UNCHECKED #include <String.au3> ;needed for _StringAddThousandsSep #include <WindowsConstants.au3> ;needed for $WS_EX_ACCEPTFILES, $DT_END_ELLIPSIS $main=GUICreate("Sync 2 Build 5",550,400,1,1,-1,$WS_EX_ACCEPTFILES) $instructions=GUICtrlCreateLabel("Browse left, type path, or drag and drop",60,5,300,20) GUICtrlCreateLabel("Total Files",400,5,100,20) $totalfileslabel=GUICtrlCreateInput("",400,25,100,20,$ES_READONLY) GUICtrlCreateLabel("Total Size",400,45,100,20) $totalsizelabel=GUICtrlCreateInput("",400,65,100,20,$ES_READONLY) $sourcebtn=GUICtrlCreateButton("Source",5,25,50,20) $targetbtn=GUICtrlCreateButton("Target",5,65,50,20) $addbtn=GUICtrlCreateButton("Add",315,65,50,20) $startbtn=GUICtrlCreateButton("START",485,135,60,20) $sourceinput=GUICtrlCreateInput("",60,25,250,20) $targetinput=GUICtrlCreateInput("",60,65,250,20) $job=GUICtrlCreateList("",5,160,540,215,$ES_READONLY) GUICtrlSetState($sourceinput,$GUI_DROPACCEPTED) GUICtrlSetState($targetinput,$GUI_DROPACCEPTED) GUICtrlSetState($startbtn,$GUI_HIDE) GUISetState(@SW_SHOW,$main) ControlFocus("","",$sourceinput) dim $accelkeys[1][2]=[["{ENTER}",$addbtn]] GUISetAccelerators($accelkeys) local $size ;size of task (dir or single file) local $count ;used to help with padding in the listbox local $fill ;the spacing for above local $queue ;the list of what is being copied (all tasks) local $totalfiles ;total number of files to be copied local $totalsize ;total byte count of files local $donesofar ;total bytes copied so far local $bytes ;used as placeholder in __Progress local $failedfiles ;string of failed copies local $failed ;count of failures Local $destination,$statusrefresh,$copyfiletime,$sourcesize,$progressbar,$xferspd,$copystatus,$cancelbtn,$pid Global $statusrefresh = 5 local $transferspeed local $formattedfile Do $msg=GUIGetMsg() if $msg=$GUI_EVENT_CLOSE then Exit if $msg=$sourcebtn then GUICtrlSetData($sourceinput,FileSelectFolder("Select a folder","")) if $msg=$targetbtn then GUICtrlSetData($targetinput,FileSelectFolder("Select a folder","",1)) if $msg=$addbtn Then $source=GUICtrlRead($sourceinput) $target=GUICtrlRead($targetinput) if not FileExists($target) then DirCreate($target) if FileExists($source) and FileExists($target) Then $wait=GUICtrlCreateLabel("Please wait, files are being enumerated",100,100,400,20) If StringInStr(FileGetAttrib($source), "D") > 0 Then $count+=1 for $padding=1 to $count $fill&=" " Next $sourceinfo=DirGetSize($source,1) GUICtrlSetData($job,$source&" -> "&$target) GUICtrlSetData($job,"("&_StringAddThousandsSep($sourceinfo[1])&" files "&_StringAddThousandsSep(round($sourceinfo[0]/1000000,2))&"MB)") GUICtrlSetData($job,$fill) $size+=$sourceinfo[0] $totalfiles+=$sourceinfo[1] $totalsize+=$sourceinfo[0] $queue&=$source&chr(1)&$target&chr(1)&"D"&chr(1) GUICtrlSetData($sourceinput,"") GUICtrlSetData($targetinput,"") GUICtrlSetData($totalfileslabel,_StringAddThousandsSep($totalfiles)) GUICtrlSetData($totalsizelabel,_StringAddThousandsSep(round($totalsize/1000000,2))&"MB") GUICtrlDelete($wait) ControlFocus("","",$sourceinput) GUICtrlSetState($startbtn,$GUI_SHOW) Else $count+=1 for $padding=1 to $count $fill&=" " Next $sourceinfo=FileGetSize($source) GUICtrlSetData($job,$source&" -> "&$target) GUICtrlSetData($job,"(1 file "&_StringAddThousandsSep(round($sourceinfo/1000000,2))&"MB)") GUICtrlSetData($job,$fill) $size+=$sourceinfo $totalfiles+=1 $totalsize+=$sourceinfo $queue&=$source&chr(1)&$target&chr(1)&"F"&chr(1) GUICtrlSetData($sourceinput,"") GUICtrlSetData($targetinput,"") GUICtrlSetData($totalfileslabel,_StringAddThousandsSep($totalfiles)) GUICtrlSetData($totalsizelabel,_StringAddThousandsSep(round($totalsize/1000000,2))&"MB") GUICtrlDelete($wait) ControlFocus("","",$sourceinput) GUICtrlSetState($startbtn,$GUI_SHOW) EndIf Else msgbox(0,"Error","Please check your source and target paths") EndIf EndIf ;end $addbtn if $msg=$startbtn Then $display=TimerInit() $howlong=TimerInit() GUICtrlDelete($startbtn) GUICtrlDelete($instructions) ControlDisable("","",$sourcebtn) ControlDisable("","",$targetbtn) ControlDisable("","",$addbtn) ControlDisable("","",$startbtn) ControlDisable("","",$sourceinput) ControlDisable("","",$targetinput) ControlDisable("","",$job) $fileprog=GUICtrlCreateProgress(5,375,265,20) $totalprog=GUICtrlCreateProgress(280,375,265,20) $stop=GUICtrlCreateCheckbox("STOP",495,135,60,20) $showfilename=GUICtrlCreateLabel("",10,100,530,20,$DT_END_ELLIPSIS) GUICtrlCreateLabel("Overall progress - ",10,125,430,20) $showtotalprog=GUICtrlCreateLabel("",96,125,230,20) $breaksources=StringSplit($queue,chr(1)) for $doit=1 to ($breaksources[0]-1) step 3 if $breaksources[$doit+2]="D" then $basedir=$breaksources[$doit] $target=$breaksources[$doit+1] $baselen = StringLen($basedir) theheart($basedir) EndIf if $breaksources[$doit+2]="F" then $source=$breaksources[$doit] $target=$breaksources[$doit+1] $name=StringTrimLeft($source,StringInStr($source,"\",0,-1)) $copyfiletime=0 $sourcesize=FileGetSize($source) $destination=$target&"\"&$name copyfile($source,$destination) if FileGetSize($source)<>FileGetSize($destination) Then $failed+=1 $failedfiles&=$formattedfile&chr(2) EndIf EndIf Next GUICtrlDelete($fileprog) GUICtrlDelete($totalprog) GUICtrlSetData($showfilename,"") $totaltimetorun=TimerDiff($howlong) $minutes=round($totaltimetorun/60000,2) if $failed=0 then msgbox(0,"Finished in "&$minutes&" minutes","Finished with no errors") if $failed<>0 then $yesorno=msgbox(4,"Finished in "&$minutes&" minutes","Finished with "&$failed&" errors, do you want to see the failed files?") if $yesorno=6 then $failedwindow=GUICreate("Failed Files",@DesktopWidth,300) ;to display the failed files $failedlist=GUICtrlCreateList("",5,5,@DesktopWidth-10,290) ;to display the failed files GUISetState(@sw_show,$failedwindow) ;done setting up GUI StringTrimRight($failedfiles,1) ;take off the trailing delimeter $failedarray=StringSplit($failedfiles,chr(2)) ;break up the list of failed files for $show=1 to $failedarray[0]-1 GUICtrlSetData($failedlist,$failedarray[$show]) ;list the failed files Next Do $msg=GUIGetMsg() if $msg=$GUI_EVENT_CLOSE then exit ;when the failed window is closed, quit the program until 1=2 EndIf EndIf Exit EndIf ;end $startbtn until 1=2 Func theheart($basedir) While GUICtrlRead($stop) == 1 ;look for the pause button $quit=msgbox(36,"Paused","Quit Now?") if $quit=6 then exit ;yes if $quit=7 then GUICtrlSetState($stop,$GUI_UNCHECKED) ;no, so uuncheck the box WEnd $basesearch = FileFindFirstFile($basedir & "\*.*") If $basesearch == -1 Then Return 0 ; specified folder is empty! While @error <> 1 $basefile = FileFindNextFile($basesearch) ; skip these If $basefile == "." Or $basefile == ".." Or $basefile == "" Then ContinueLoop EndIf ; if it's a dir then call this function again (nesting the function is clever ;) $formattedfile = $basedir & "\" & $basefile If StringInStr(FileGetAttrib($formattedfile), "D") > 0 Then theheart($formattedfile) Else ; Files we need to deal with $dest=StringTrimLeft($formattedfile,$baselen) While GUICtrlRead($stop) == 1 ;look for the pause button $quit=msgbox(36,"Paused","Quit Now?") if $quit=6 then exit ;yes if $quit=7 then GUICtrlSetState($stop,$GUI_UNCHECKED) ;no, so uuncheck the box WEnd GUICtrlSetData($showfilename,$formattedfile);&" - "&$BytesTransferred / $FileSize * 100&"%") if not FileExists($target&$dest) then $copyfiletime=0 $source=$formattedfile $sourcesize=FileGetSize($source) $destination=$target&$dest $lastdir=$target&StringMid($dest,1,StringInStr($dest,"\",2,-1)-1) if not FileExists($lastdir) then DirCreate($lastdir) copyfile($source,$destination) if FileGetSize($source)<>FileGetSize($destination) Then $failed+=1 $failedfiles&=$formattedfile&chr(2) EndIf ;~ Else EndIf $donesofar+=FileGetSize($formattedfile) GUICtrlSetData($showtotalprog,round($donesofar / $size * 100,4)&"%") GUICtrlSetData($totalprog,$donesofar / $size * 100) ;~ EndIf $lastbyte=0 $bytes=0 endif WEnd FileClose($basesearch) Return 1 EndFunc ;end theheart func copyfile($source,$destination) Dim $starttime = TimerInit() $pid = Run(@ComSpec & " /c copy /y " & chr(34) & $source & chr(34) & " " & chr(34) & $destination & chr(34), @ScriptDir, @SW_HIDE) If ($pid = 0) Then ;~ MsgBox(16, "Error", "Error running copy command") ;~ Exit EndIf While (ProcessExists($pid)) $procstats = ProcessGetStats($pid, 1) If (IsArray($procstats) And UBound($procstats) > 4) Then If (Int(timerdiff($starttime)) > $statusrefresh) Then $transferspeed = $procstats[4] $transfersize = $procstats[4] $starttime = TimerInit() $progresstime = TimerInit() EndIf $destinationsize = $procstats[4] If ($destinationsize > $sourcesize) Then $destinationsize = $sourcesize EndIf $progress = $destinationsize / $sourcesize * 100 ;~ $donesofar+= GUICtrlSetData($showtotalprog,round($donesofar / $size * 100,4)&"%") GUICtrlSetData($totalprog,$donesofar / $size * 100) GUICtrlSetData($fileprog, $progress) EndIf Sleep(5) WEnd EndFunc Func killproc($pid) ; kills a process While (ProcessExists($pid)) ProcessClose($pid) WEnd EndFunc Func cancelop() ; If copystatus = 0 (not copying...) If ($copystatus = 0) Then GUISetState(@SW_HIDE) Exit EndIf If (MsgBox(4 + 32 + 256, "Copy File Progress", "Are you sure you want to cancel file copy?") = 6) Then GUICtrlSetState($cancelbtn, $GUI_DISABLE) killproc($pid) If (FileExists($destination)) Then FileDelete($destination) EndIf Exit EndIf EndFunc Ian My projects: IP Scanner - Multi-threaded ping tool to scan your available networks for used and available IP addresses, shows ping times, resolves IPs in to host names, and allows individual IPs to be pinged. INFSniff - Great technicians tool - a tool which scans DriverPacks archives for INF files and parses out the HWIDs to a database file, and rapidly scans the local machine's HWIDs, searches the database for matches, and installs them. PPK3 (Persistent Process Killer V3) - Another for the techs - suppress running processes that you need to keep away, helpful when fighting spyware/viruses. Sync Tool - Folder sync tool with lots of real time information and several checking methods. USMT Front End - Front End for Microsoft's User State Migration Tool, including all files needed for USMT 3.01 and 4.01, 32 bit and 64 bit versions. Audit Tool - Computer audit tool to gather vital hardware, Windows, and Office information for IT managers and field techs. Capabilities include creating a customized site agent. CSV Viewer - Displays CSV files with automatic column sizing and font selection. Lines can also be copied to the clipboard for data extraction. MyDirStat - Lists number and size of files on a drive or specified path, allows for deletion within the app. 2048 Game - My version of 2048, fun tile game. Juice Lab - Ecigarette liquid making calculator. Data Protector - Secure notes to save sensitive information. VHD Footer - Add a footer to a forensic hard drive image to allow it to be mounted or used as a virtual machine hard drive. Find in File - Searches files containing a specified phrase. Link to comment Share on other sites More sharing options...
shovetech Posted December 22, 2009 Share Posted December 22, 2009 llewxam: I like your thinking about a dual progress bar. One for current file, and one for total transfer complete. I've updated my code once again to add decimal places when displaying byte data in variable (default is 2). I also tried my attempt at the dual progress bar idea. As of this post, version is v1.1.3 Link to comment Share on other sites More sharing options...
llewxam Posted December 22, 2009 Author Share Posted December 22, 2009 Looking good, couple things though: Line 250, $destinationesize should be $destinationsize There is a command for what your "shortText" function does, add #include <WindowsConstants.au3> and set $DT_END_ELLIPSIS as style for GUICtrlCreateLabel. You would have to make 2 Labels instead of linebreaking one as in $lblfiles, and just use a static Label to show "Source:" and "Destination:", and use $DT_END_ELLIPSIS for the Labels showing $source and $destination. For me this was much easier than manually coding it, is faster, and is more consistent. Otherwise very good, glad you dig the dual progbars Ian My projects: IP Scanner - Multi-threaded ping tool to scan your available networks for used and available IP addresses, shows ping times, resolves IPs in to host names, and allows individual IPs to be pinged. INFSniff - Great technicians tool - a tool which scans DriverPacks archives for INF files and parses out the HWIDs to a database file, and rapidly scans the local machine's HWIDs, searches the database for matches, and installs them. PPK3 (Persistent Process Killer V3) - Another for the techs - suppress running processes that you need to keep away, helpful when fighting spyware/viruses. Sync Tool - Folder sync tool with lots of real time information and several checking methods. USMT Front End - Front End for Microsoft's User State Migration Tool, including all files needed for USMT 3.01 and 4.01, 32 bit and 64 bit versions. Audit Tool - Computer audit tool to gather vital hardware, Windows, and Office information for IT managers and field techs. Capabilities include creating a customized site agent. CSV Viewer - Displays CSV files with automatic column sizing and font selection. Lines can also be copied to the clipboard for data extraction. MyDirStat - Lists number and size of files on a drive or specified path, allows for deletion within the app. 2048 Game - My version of 2048, fun tile game. Juice Lab - Ecigarette liquid making calculator. Data Protector - Secure notes to save sensitive information. VHD Footer - Add a footer to a forensic hard drive image to allow it to be mounted or used as a virtual machine hard drive. Find in File - Searches files containing a specified phrase. 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