Matt Houston Posted April 28, 2006 Share Posted April 28, 2006 Hi, I would like to combine my script with robocopy in order to get some (per-file) percentage values. Basically it's working but i'm stuck with parsing the data. Here's my code so far (not much indeed...): #include <constants.au3> $sourcedir = "c:\copytest\" $destdir = "c:\copytest2\" $copyjob = Run (@ComSpec & " /c " & 'robocopy.exe ' & $sourcedir & ' ' & $destdir & ' /E /NJH /NJS /NDL /NC', @ScriptDir, @SW_HIDE, $STDOUT_CHILD) While 1 $line = StdoutRead($copyjob) If @error = -1 Then ExitLoop MsgBox(0, "STDOUT read:", $line) Wend I just used a message box to see if anything is read by StoudRead - that's working! The message box is FULL of info! At the moment the fetched data looks like this: filesize filename.exe 1% 2% 4% 6% 7% 8% .... My question is: Is it possible to "StdoutRead-line-by-line"? Is there some way to parse the info? My idea was to get this line by line and parse it in order to get the single values (this is the actual output from robocopy in the cmd box): 100% 4.2 m c:\copytest\file1.xls 100% 53248 c:\copytest\file2.exe 100% 52 c:\copytest\file3.ini Maybe somebody as a few hints to get me back on track... Greetings, MattHouston Link to comment Share on other sites More sharing options...
dabus Posted April 28, 2006 Share Posted April 28, 2006 (edited) Maybe you could add something like If StringLeft($line, 4) = "100%" Then MsgBox(0, "STDOUT read:", $line) ??? I don't have a copy to test it now, so it's up to you . Have a look at tail if this doesn't do the trick. Edited April 28, 2006 by dabus Link to comment Share on other sites More sharing options...
neogia Posted April 28, 2006 Share Posted April 28, 2006 Post the output from here: #include <constants.au3> $sourcedir = "c:\copytest\" $destdir = "c:\copytest2\" $copyjob = Run (@ComSpec & " /c " & 'robocopy.exe ' & $sourcedir & ' ' & $destdir & ' /E /NJH /NJS /NDL /NC', @ScriptDir, @SW_HIDE, $STDOUT_CHILD) $output = "" While ProcessExists($copyjob) If StdoutRead($copyjob, 0, true) > 0 Then $output &= StdoutRead($copyjob) EndIf Sleep(1000) WEnd If StdoutRead($copyjob, 0, true) > 0 Then $output &= StdoutRead($copyjob) EndIf ClipPut($output); So you can copy it into the forums MsgBox(0,"",$output) If you post the output from there (all of the output amassed into one string), and then tell exactly what you want parsed out of it, then I should be able to help you out. You could also have a look at StringRegExp guide, in my signature, it tells you (not all of) how to use the function StringRegExp() to parse text. [u]My UDFs[/u]Coroutine Multithreading UDF LibraryStringRegExp GuideRandom EncryptorArrayToDisplayString"The Brain, expecting disaster, fails to find the obvious solution." -- neogia Link to comment Share on other sites More sharing options...
Matt Houston Posted April 28, 2006 Author Share Posted April 28, 2006 (edited) neogia - thanks for your help! I didn't even know ClipPut So here's what i got: 4.2 m c:\copytest\filename1.xls 0% 1% 2% 4% 5% 7% 8% 10% 11% ........ 94% 96% 97% 99% 100% 53248 c:\copytest\filename2.EXE 0% 100% 147654 c:\copytest\filename3.bmp 0% 44% 88% 100%I just shortened it a bit in the middle - no need to watch all those numbers... I would like to use these three values (percentage, filesize and filename) to make a progress bar / progress window. I will definately read your guide - but i'm unsure if i find the time today. Again, thank you very much for your help! I really appreciate that! Matt Edited April 28, 2006 by Matt Houston Link to comment Share on other sites More sharing options...
neogia Posted April 28, 2006 Share Posted April 28, 2006 Alright, this should get you started, I'll leave the GUI part to you, it's good to learn. What I've done here is created a StringRegExp that will either return an array of one element (If it is a progress update line [0] = progress in percent) or two elements (If it is a new file being copied [0] = filesize [1] = filename). I've also set up the loop that should run after you start the robocopy job. It assumes you save the PID from the Run() command in the variable $copyjob. expandcollapse popupWhile ProcessExists($copyjob) If StdoutRead($copyjob, 0, true) > 0 Then $output &= StdoutRead($copyjob) If StringInStr($output, @CRLF) Then $output = StringSplit($output, @CRLF) For $i = 1 To $output[0] $result = StringRegExp($output[$i], '(\d+%)|([0-9\\.]+\s*[mg]?)\s*(.*)', 1) If IsArray($result) Then If StringInStr($result[0], "%") Then; Current line is a progress update line ; Set current progress bar to StringTrimRight($result[0], 1) ; Set current progress percent label to $result[0] Else; Current line is a new file line ; Reset progress bar to 0 ; Reset progress percent label to "0%" ; Set current file size label to $result[0] (either a number in bytes or something like (4.2 m) ; Set current file name label to $result[1] (outputted as full filepath) EndIf EndIf Next EndIf EndIf WEnd ; Do one more in case there's any output left in the stream after the $copyjob closes If StdoutRead($copyjob, 0, true) > 0 Then $output &= StdoutRead($copyjob) If StringInStr($output, @CRLF) Then $output = StringSplit($output, @CRLF) For $i = 1 To $output[0] $result = StringRegExp($output[$i], '(\d+%)|([0-9\\.]+\s*[mg]?)\s*(.*)', 1) If IsArray($result) Then If StringInStr($result[0], "%") Then; Current line is a progress update line ; Set current progress bar to StringTrimRight($result[0], 1) ; Set current progress percent label to $result[0] Else; Current line is a new file line ; Reset progress bar to 0 ; Reset progress percent label to "0%" ; Set current file size label to $result[0] (either a number in bytes or something like (4.2 m) ; Set current file name label to $result[1] (outputted as full filepath) EndIf EndIf Next EndIf EndIf [u]My UDFs[/u]Coroutine Multithreading UDF LibraryStringRegExp GuideRandom EncryptorArrayToDisplayString"The Brain, expecting disaster, fails to find the obvious solution." -- neogia Link to comment Share on other sites More sharing options...
blindwig Posted April 28, 2006 Share Posted April 28, 2006 I had this same issue a while back. The solution is to run RoboCopy with the "/np" option. Also note that RoboCopy has a "/tee" parameter which works very much like the linux tee command. RoboCopy has a ton of options, do a "/?" to see them. It also comes with a pretty good manual. My UDF Threads:Pseudo-Hash: Binary Trees, Flat TablesFiles: Filter by Attribute, Tree List, Recursive Find, Recursive Folders Size, exported to XMLArrays: Nested, Pull Common Elements, Display 2dSystem: Expand Environment Strings, List Drives, List USB DrivesMisc: Multi-Layer Progress Bars, Binary FlagsStrings: Find Char(s) in String, Find String in SetOther UDF Threads I Participated:Base64 Conversions Link to comment Share on other sites More sharing options...
neogia Posted April 28, 2006 Share Posted April 28, 2006 ...I had this same issue a while back...What issue? And what would /np or /tee do to help? [u]My UDFs[/u]Coroutine Multithreading UDF LibraryStringRegExp GuideRandom EncryptorArrayToDisplayString"The Brain, expecting disaster, fails to find the obvious solution." -- neogia Link to comment Share on other sites More sharing options...
dabus Posted April 28, 2006 Share Posted April 28, 2006 I think np could be no-process. tee writes output to stdout and a file. Link to comment Share on other sites More sharing options...
blindwig Posted April 28, 2006 Share Posted April 28, 2006 (edited) Oops, sorry I got this post mixed up with another one I was helping with RoboCopy. the "/np" parameter turns off the percentage signs. What you want to do is read a line and parse the file name out of it. if the line has a percentage sign in it, then it is a percentage for the last file. Since a file cannot has a percentage sign in it's name, then you automatically know that all lines that contain percentage signs are progress marks for the last-mentioned file. Some other options you might want to look into are /NJH /NJS /ETA. Again I will say that using the /? and the RoboCopy documentation will answer all your questions. I've been doing some automation using RoboCopy to synchronize folders and shares and I have to say that it is well documented. Here is the command summary ( /? ) for reference for those who are trying to help that do not have RoboCopy installed: expandcollapse popup------------------------------------------------------------------------------- ROBOCOPY :: Robust File Copy for Windows :: Version XP010 ------------------------------------------------------------------------------- Started : Fri Apr 28 14:07:36 2006 Usage :: ROBOCOPY source destination [file [file]...] [options] source :: Source Directory (drive:\path or \\server\share\path). destination :: Destination Dir (drive:\path or \\server\share\path). file :: File(s) to copy (names/wildcards: default is "*.*"). :: :: Copy options : :: /S :: copy Subdirectories, but not empty ones. /E :: copy subdirectories, including Empty ones. /LEV:n :: only copy the top n LEVels of the source directory tree. /Z :: copy files in restartable mode. /B :: copy files in Backup mode. /ZB :: use restartable mode; if access denied use Backup mode. /COPY:copyflag[s] :: what to COPY (default is /COPY:DAT). (copyflags : D=Data, A=Attributes, T=Timestamps). (S=Security=NTFS ACLs, O=Owner info, U=aUditing info). /SEC :: copy files with SECurity (equivalent to /COPY:DATS). /COPYALL :: COPY ALL file info (equivalent to /COPY:DATSOU). /NOCOPY :: COPY NO file info (useful with /PURGE). /PURGE :: delete dest files/dirs that no longer exist in source. /MIR :: MIRror a directory tree (equivalent to /E plus /PURGE). /MOV :: MOVe files (delete from source after copying). /MOVE :: MOVE files AND dirs (delete from source after copying). /A+:[RASHNT] :: add the given Attributes to copied files. /A-:[RASHNT] :: remove the given Attributes from copied files. /CREATE :: CREATE directory tree and zero-length files only. /FAT :: create destination files using 8.3 FAT file names only. /FFT :: assume FAT File Times (2-second granularity). /256 :: turn off very long path (> 256 characters) support. /MON:n :: MONitor source; run again when more than n changes seen. /MOT:m :: MOnitor source; run again in m minutes Time, if changed. /RH:hhmm-hhmm :: Run Hours - times when new copies may be started. /PF :: check run hours on a Per File (not per pass) basis. /IPG:n :: Inter-Packet Gap (ms), to free bandwidth on slow lines. :: :: File Selection Options : :: /A :: copy only files with the Archive attribute set. /M :: copy only files with the Archive attribute and reset it. /IA:[RASHCNETO] :: Include only files with any of the given Attributes set. /XA:[RASHCNETO] :: eXclude files with any of the given Attributes set. /XF file [file]... :: eXclude Files matching given names/paths/wildcards. /XD dirs [dirs]... :: eXclude Directories matching given names/paths. /XC :: eXclude Changed files. /XN :: eXclude Newer files. /XO :: eXclude Older files. /XX :: eXclude eXtra files and directories. /XL :: eXclude Lonely files and directories. /IS :: Include Same files. /IT :: Include Tweaked files. /MAX:n :: MAXimum file size - exclude files bigger than n bytes. /MIN:n :: MINimum file size - exclude files smaller than n bytes. /MAXAGE:n :: MAXimum file AGE - exclude files older than n days/date. /MINAGE:n :: MINimum file AGE - exclude files newer than n days/date. /MAXLAD:n :: MAXimum Last Access Date - exclude files unused since n. /MINLAD:n :: MINimum Last Access Date - exclude files used since n. (If n < 1900 then n = n days, else n = YYYYMMDD date). /XJ :: eXclude Junction points. (normally included by default). :: :: Retry Options : :: /R:n :: number of Retries on failed copies: default 1 million. /W:n :: Wait time between retries: default is 30 seconds. /REG :: Save /R:n and /W:n in the Registry as default settings. /TBD :: wait for sharenames To Be Defined (retry error 67). :: :: Logging Options : :: /L :: List only - don't copy, timestamp or delete any files. /X :: report all eXtra files, not just those selected. /V :: produce Verbose output, showing skipped files. /TS :: include source file Time Stamps in the output. /FP :: include Full Pathname of files in the output. /NS :: No Size - don't log file sizes. /NC :: No Class - don't log file classes. /NFL :: No File List - don't log file names. /NDL :: No Directory List - don't log directory names. /NP :: No Progress - don't display % copied. /ETA :: show Estimated Time of Arrival of copied files. /LOG:file :: output status to LOG file (overwrite existing log). /LOG+:file :: output status to LOG file (append to existing log). /TEE :: output to console window, as well as the log file. /NJH :: No Job Header. /NJS :: No Job Summary. :: :: Job Options : :: /JOB:jobname :: take parameters from the named JOB file. /SAVE:jobname :: SAVE parameters to the named job file /QUIT :: QUIT after processing command line (to view parameters). /NOSD :: NO Source Directory is specified. /NODD :: NO Destination Directory is specified. /IF :: Include the following Files. Edited April 28, 2006 by blindwig My UDF Threads:Pseudo-Hash: Binary Trees, Flat TablesFiles: Filter by Attribute, Tree List, Recursive Find, Recursive Folders Size, exported to XMLArrays: Nested, Pull Common Elements, Display 2dSystem: Expand Environment Strings, List Drives, List USB DrivesMisc: Multi-Layer Progress Bars, Binary FlagsStrings: Find Char(s) in String, Find String in SetOther UDF Threads I Participated:Base64 Conversions Link to comment Share on other sites More sharing options...
Simucal Posted April 29, 2006 Share Posted April 29, 2006 (edited) Well.. I wrote this without seeing that neogia had posted a solution already. His is much more elegant. So, here is one that will give you a Progress bar with the filepath, filesize, and % completed. #include <Constants.au3> $sourcedir = "c:\copytest\" $destdir = "c:\copytest2\" $ourProcess = Run (@ComSpec & " /c " & 'robocopy.exe ' & $sourcedir & ' ' & $destdir & ' /E /NJH /NJS /NDL /NC', @ScriptDir, @SW_HIDE, $STDOUT_CHILD) ProgressOn("RoboCopy", "Copying Files...", "0%",-1,-1,18) While 1 If $ourProcess Then $charsWaiting = StdoutRead($ourProcess, 0 , 1) If @error = -1 Then $ourProcess = 0 MsgBox(0, "App Exited", "Process has exited...") ContinueLoop EndIf If $charsWaiting Then $currentRead = StdoutRead($ourProcess) $fileinfo = StringRegExp($currentRead, '(.*?)([:alpha:]:.*\.[a-zA-Z]{3})',3) If IsArray($fileinfo) = 1 Then $filesize = StringStripCR(StringStripWS($fileinfo[0],8)) $filename = $fileinfo[1] EndIf $percent = StringRegExp($currentRead, '([0-9]{1,3})(?:.[0-9]{1,3})(?:%)',3) If IsArray($percent) = 1 Then ProgressSet($percent[0],$percent[0]&"% "&@CRLF&"Filename: "&$filename&@CRLF&"Filesize: "&$filesize) EndIf EndIf EndIf WEnd ProgressOff() Exit Edited April 29, 2006 by Simucal AutoIt Scripts:Aimbot: Proof of Concept - PixelSearching Aimbot with several search/autoshoot/lock-on techniques.Sliding Toolbar - Add a nice Sliding Toolbar to your next script. Click the link to see an animation of it in action!FontInfo UDF - Get list of system fonts, or search to see if a particular font is installed.Get Extended Property UDF - Retrieve a files extended properties (e.g., video/image dimensions, file version, bitrate of song/video, etc) Link to comment Share on other sites More sharing options...
Matt Houston Posted May 3, 2006 Author Share Posted May 3, 2006 Thanks for your help mates! Sorry that i could not get back earlier... (way too much work these days...) @neogia: i just had a quick go on your script - unfortunately it did not work (at least my part...) i tried to build a prograssbar around it - with no success. if i understood the concept i need to create the progressbar *BEFORE* the loop starts, the update should then be done inside the loop, right? ... If IsArray($result) Then If StringInStr($result[0], "%") Then; Current line is a progress update line $progress = StringTrimRight($result[0], 1) MsgBox (4096,"Test", $progress) ... I just used a message box in order to see if this part is running - i also tried to update a progressbar at this point. One small thing - on line number three your script says: $output &= StdoutRead($copyjob)Is the "&" a typo? @simucal: Your script is working - for one file. As soon, as there are some more files in the folder it struggles and the progressbar is no longer updated. Unfortunately i don't have the time to investigate all this at the moment. My boss gave me some high priority tasks - so i will get back to this in about 2 weeks. But at least i wanted to thank you for your support! I learned a lot in this forum and i'm sure we will get this working too! So long! Matt Houston Link to comment Share on other sites More sharing options...
neogia Posted May 3, 2006 Share Posted May 3, 2006 $output &= StdoutRead($copyjob) Is not a typo: it means "concatenate StdoutRead($copyjob) to whatever's already in $output". It's equivalent to: $output = $output & StdoutRead($copyjob) Could you maybe post the files that you're using, and I can work on finding out why neither mine nor simucal's scripts are working sufficiently? Like robocopy.exe and a test input file? [u]My UDFs[/u]Coroutine Multithreading UDF LibraryStringRegExp GuideRandom EncryptorArrayToDisplayString"The Brain, expecting disaster, fails to find the obvious solution." -- neogia Link to comment Share on other sites More sharing options...
Matt Houston Posted May 4, 2006 Author Share Posted May 4, 2006 $output &= StdoutRead($copyjob) Is not a typo: it means "concatenate StdoutRead($copyjob) to whatever's already in $output". It's equivalent to: $output = $output & StdoutRead($copyjob)Ooops... Have to read more about the syntax... Could you maybe post the files that you're using, and I can work on finding out why neither mine nor simucal's scripts are working sufficiently? Like robocopy.exe and a test input file?Sure - robocopy.exe is attached to this post. I think that's ok, as Microsoft is distributing this freely. I don't think that it is important to use the same files which i've been using. I just picked some random files (i always took one larger file (200 MB), because otherwise the script does not run long enough). Greetings, MattHoustonrobocopy.zip Link to comment Share on other sites More sharing options...
neogia Posted May 4, 2006 Share Posted May 4, 2006 Well, this is a working script, but it's a little fishy: with large files, it appears that robocopy spews out thousands and thousands of percentage updates, which causes a delay in the update of the progress bar. After the delay, the progress updates smoothly, but I'm sure there's a way to either skip some of the percentage updates or something to prevent that lag. Anywho, here's a script for you to play around with at least: expandcollapse popup#include <GUIConstants.au3> $GUI = GUICreate("Progress", 300, 100) GUICtrlCreateLabel("Current File: ", 10, 10) $fileLbl = GUICtrlCreateLabel("N/A", 75, 10, 225) GUICtrlCreateLabel("Current File Size: ", 10, 25) $sizeLbl = GUICtrlCreateLabel("N/A", 95, 25, 105) $progress = GUICtrlCreateProgress(10, 50, 280) GUISetState() $sourcedir = "c:\copytest\" $destdir = "c:\copytest2\" $copyjob = Run (@ComSpec & " /c " & 'robocopy.exe ' & $sourcedir & ' ' & $destdir, @ScriptDir, @SW_HIDE, 7) $output = "" $switch = 0; We don't want to run StringRegExp on lines that don't matter to us While ProcessExists($copyjob) If StdoutRead($copyjob, 0, true) > 0 Then $output &= StdoutRead($copyjob) If StringInStr($output, @CRLF) Then $output = StringSplit($output, @CRLF) For $i = 1 To $output[0] - 1 If Not $switch Then If StringRegExp($output[$i], '\d+\s+' & StringReplace($sourcedir, "\", "\\")) == 1 Then $switch = Not $switch $i += 1 EndIf EndIf If $switch Then $result = StringRegExp($output[$i], '([0-9.]+%)|([0-9.]+\s*[mg]?)\s*(.*)', 1) If IsArray($result) Then If StringInStr($result[0], "%") Then; Current line is a progress update line ; Set current progress bar to StringTrimRight($result[0], 1) GUICtrlSetData($progress, StringTrimRight($result[0], 1)) ; Set current progress percent label to $result[0] Else; Current line is a new file line ; Reset progress bar to 0 GUICtrlSetData($progress, 0) ; Reset progress percent label to "0%" ; Set current file size label to $result[0] (either a number in bytes or something like (4.2 m) GUICtrlSetData($sizeLbl, $result[0]) ; Set current file name label to $result[1] (outputted as full filepath) GUICtrlSetData($fileLbl, $result[1]) EndIf EndIf EndIf Next $output = $output[$output[0]] EndIf EndIf WEnd ; Do one more in case there's any output left in the stream after the $copyjob closes If StdoutRead($copyjob, 0, true) > 0 Then $output &= StdoutRead($copyjob) If StringInStr($output, @CRLF) Then $output = StringSplit($output, @CRLF) For $i = 1 To $output[0] If Not $switch Then If StringRegExp($output[$i], '\d+\s+' & StringReplace($sourcedir, "\", "\\")) Then $switch = Not $switch $i += 1 EndIf EndIf If $switch Then $result = StringRegExp($output[$i], '([0-9.]+%)|([0-9.]+\s*[mg]?)\s*(.*)', 1) If IsArray($result) Then If StringInStr($result[0], "%") Then; Current line is a progress update line ; Set current progress bar to StringTrimRight($result[0], 1) GUICtrlSetData($progress, StringTrimRight($result[0], 1)) ; Set current progress percent label to $result[0] Else; Current line is a new file line ; Reset progress bar to 0 GUICtrlSetData($progress, 0) ; Reset progress percent label to "0%" ; Set current file size label to $result[0] (either a number in bytes or something like (4.2 m) GUICtrlSetData($sizeLbl, $result[0]) ; Set current file name label to $result[1] (outputted as full filepath) GUICtrlSetData($fileLbl, $result[1]) EndIf EndIf EndIf Next EndIf EndIf Note: You'll have to try files > ~50Mb for a human to be able to read the output. [u]My UDFs[/u]Coroutine Multithreading UDF LibraryStringRegExp GuideRandom EncryptorArrayToDisplayString"The Brain, expecting disaster, fails to find the obvious solution." -- neogia Link to comment Share on other sites More sharing options...
rgaspar Posted September 10, 2008 Share Posted September 10, 2008 Hello, Anyone have a all code complete with progressbar? I trie use this code but copy files, not copy folders, subfolders and progressbar not run. My project is copy one disk partition with letter D:\ (Total 60gb) to folder user that this to my server. Link to comment Share on other sites More sharing options...
happyuser Posted November 8, 2008 Share Posted November 8, 2008 Hi, I have the same sort of question (see http://www.autoitscript.com/forum/index.php?showtopic=84017 ). I want to show a progress bar but it doesn't work. I have tried the example up here. Same behaviour. The task runs in the background, the copy is effective but nothing is visible in the progress bar. I suspect that the StdoutRead never returns before completing of external task even with the switch "peek" (3rd parameter). It returns at the end with the total output of external task. Not what I need. Does someone of the development team can address such a problem? Thank you. Regards Link to comment Share on other sites More sharing options...
Gigglestick Posted April 21, 2009 Share Posted April 21, 2009 Sorry to resurrect an old thread, but I thought it might be worth mentioning that each time a percentage is output by robocopy, it prepends it with an @LF, not a @CRLF. If you manually run robocopy, you'll notice that the percent is always at the beginning of the line; it doesn't scroll, thus the @LF only. Watching for the @LF and taking from that to the % sign will give you your percentage. Compare that to the percent you already have and only update the progress bar if it has changed to avoid the thousands of updates issue. My UDFs: ExitCodes Link to comment Share on other sites More sharing options...
NoelG Posted April 22, 2009 Share Posted April 22, 2009 Well, this is a working script, but it's a little fishy: with large files, it appears that robocopy spews out thousands and thousands of percentage updates, which causes a delay in the update of the progress bar. After the delay, the progress updates smoothly, but I'm sure there's a way to either skip some of the percentage updates or something to prevent that lag. Anywho, here's a script for you to play around with at least: expandcollapse popup#include <GUIConstants.au3> $GUI = GUICreate("Progress", 300, 100) GUICtrlCreateLabel("Current File: ", 10, 10) $fileLbl = GUICtrlCreateLabel("N/A", 75, 10, 225) GUICtrlCreateLabel("Current File Size: ", 10, 25) $sizeLbl = GUICtrlCreateLabel("N/A", 95, 25, 105) $progress = GUICtrlCreateProgress(10, 50, 280) GUISetState() $sourcedir = "c:\copytest\" $destdir = "c:\copytest2\" $copyjob = Run (@ComSpec & " /c " & 'robocopy.exe ' & $sourcedir & ' ' & $destdir, @ScriptDir, @SW_HIDE, 7) $output = "" $switch = 0; We don't want to run StringRegExp on lines that don't matter to us While ProcessExists($copyjob) If StdoutRead($copyjob, 0, true) > 0 Then $output &= StdoutRead($copyjob) If StringInStr($output, @CRLF) Then $output = StringSplit($output, @CRLF) For $i = 1 To $output[0] - 1 If Not $switch Then If StringRegExp($output[$i], '\d+\s+' & StringReplace($sourcedir, "\", "\\")) == 1 Then $switch = Not $switch $i += 1 EndIf EndIf If $switch Then $result = StringRegExp($output[$i], '([0-9.]+%)|([0-9.]+\s*[mg]?)\s*(.*)', 1) If IsArray($result) Then If StringInStr($result[0], "%") Then; Current line is a progress update line ; Set current progress bar to StringTrimRight($result[0], 1) GUICtrlSetData($progress, StringTrimRight($result[0], 1)) ; Set current progress percent label to $result[0] Else; Current line is a new file line ; Reset progress bar to 0 GUICtrlSetData($progress, 0) ; Reset progress percent label to "0%" ; Set current file size label to $result[0] (either a number in bytes or something like (4.2 m) GUICtrlSetData($sizeLbl, $result[0]) ; Set current file name label to $result[1] (outputted as full filepath) GUICtrlSetData($fileLbl, $result[1]) EndIf EndIf EndIf Next $output = $output[$output[0]] EndIf EndIf WEnd ; Do one more in case there's any output left in the stream after the $copyjob closes If StdoutRead($copyjob, 0, true) > 0 Then $output &= StdoutRead($copyjob) If StringInStr($output, @CRLF) Then $output = StringSplit($output, @CRLF) For $i = 1 To $output[0] If Not $switch Then If StringRegExp($output[$i], '\d+\s+' & StringReplace($sourcedir, "\", "\\")) Then $switch = Not $switch $i += 1 EndIf EndIf If $switch Then $result = StringRegExp($output[$i], '([0-9.]+%)|([0-9.]+\s*[mg]?)\s*(.*)', 1) If IsArray($result) Then If StringInStr($result[0], "%") Then; Current line is a progress update line ; Set current progress bar to StringTrimRight($result[0], 1) GUICtrlSetData($progress, StringTrimRight($result[0], 1)) ; Set current progress percent label to $result[0] Else; Current line is a new file line ; Reset progress bar to 0 GUICtrlSetData($progress, 0) ; Reset progress percent label to "0%" ; Set current file size label to $result[0] (either a number in bytes or something like (4.2 m) GUICtrlSetData($sizeLbl, $result[0]) ; Set current file name label to $result[1] (outputted as full filepath) GUICtrlSetData($fileLbl, $result[1]) EndIf EndIf EndIf Next EndIf EndIf Note: You'll have to try files > ~50Mb for a human to be able to read the output. Dragging this one up a little further from the depths of time. I'm trying to use this very script with very little success. I've change the @CRLF to just @CR and @LF with no success. If StringInStr($output, @LF) Then $output = StringSplit($output, @LF) I've put in place some msgbox's to display the stdout data and I can see the data output and it looks like it's formatted correctly. However, I only get N/A from the Current file: and Current File Size:. The progress bar does not move either. Could there have been some changes to some of the built in functions between the version that this was written in and the current version? For example, I had to change this: StdoutRead($copyjob, 0, true) to: StdoutRead($copyjob, True, True) in order to get any stdout data to display. I've been racking my brain over this, but have yet to figure it out. Also as a side note. People who want to use this may want to change the following lines: $sourcedir = "c:\copytest\" $destdir = "c:\copytest2\" $copyjob = Run (@ComSpec & " /c " & 'robocopy.exe ' & $sourcedir & ' ' & $destdir, @ScriptDir, @SW_HIDE, 7) to: $sourcedir = '"c:\copytest\"' $destdir = '"c:\copytest2\"' $copyjob = Run (@ComSpec & " /c " & 'robocopy.exe /E /NJH /NJS' & $sourcedir & ' ' & $destdir, @ScriptDir, @SW_HIDE, 8) Use of the single quote around the double quote allows the use of spaces in the folder name for source and destdir's. Using /E /NJH /NJS makes sure that everything is copied recursively, and that you don't dirty up stdout with stuff this script does not use. I could be wrong about the script using that information, but it did not look like it. Link to comment Share on other sites More sharing options...
Symphatico Posted August 5, 2011 Share Posted August 5, 2011 (edited) Hello everybody, I'm aware that this post is rather old, but is there any news when it comes to the progressbar with robocopy? I'm looking for a suitable solution for quite some time now, but I wasn't lucky to find one yet. Looks a bit like flighing to the moon was easier then get robocopy up and running with a progressbar Any remarks/comments welcome. Edited August 5, 2011 by Symphatico Link to comment Share on other sites More sharing options...
CMarshy Posted December 1, 2011 Share Posted December 1, 2011 Probably a bit late for most of you but i have had to get a progress bar working on a Robocopy. So used this code, with several major tweaks. I had to rejig the cmd line, and the if statements werenot passing through the correct information. I've still got some more work to do on this, to tidy it up as it is just your code dumped in a function. I've also got to get a second full progress bar at the bottom for the client, which i think i will do by running a test copy first to workout the number of files and size to compare against final. expandcollapse popup#include <GUIConstants.au3> #include <file.au3> Local $tempOutput $GUI = GUICreate("Progress", 500, 200) GUICtrlCreateLabel("Current File: ", 10, 100) $fileLbl = GUICtrlCreateLabel("N/A", 75, 100, 400) GUICtrlCreateLabel("Current File Size: ", 10, 125) $sizeLbl = GUICtrlCreateLabel("N/A", 95, 125, 105) $progress = GUICtrlCreateProgress(10, 150, 480) $SourceBtn = GUICtrlCreateButton("...S",400, 35, 25, 25) $DestBtn = GUICtrlCreateButton("...D",400, 65, 25, 25) $SourceLabel = GUICtrlCreateInput("Select the Source Folder:", 10, 40, 380, 17) $DestLabel = GUICtrlCreateInput("Select the Destination Folder:", 10, 70, 380, 17) $GoBtn = GUICtrlCreateButton("GO", 225, 180, 25, 25) $ExitBtn = GUICtrlCreateButton("EXIT", 275, 180, 25, 25) GUISetState() Local $Destination, $Source While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Case $SourceBtn $Source=_GetSourceDir() GUICtrlSetData($SourceLabel,$Source) Case $DestBtn $Destination=_GetDestinationDir() GUICtrlSetData($DestLabel,$Destination) Case $GoBtn _Copier($Source, $Destination) Case $ExitBtn _ExitProgram() EndSwitch WEnd Func _ExitProgram() Exit EndFunc Func _GetSourceDir() $SourceDir=FileSelectFolder("Get Source", "", 2, "EditPlus 2") Return $SourceDir EndFunc Func _GetDestinationDir() $DestinationDir=FileSelectFolder("Select Destination", "", 1, "EditPlus 2") Return '"' & $DestinationDir & '"' Return $DestinationDir EndFunc Func _Copier($Source, $Destination) msgbox(1,"Source", $Source) msgbox(1,"Destination", $Destination) $sourcedir=$Source $destdir=$Destination $copyjob = Run (@ComSpec & " /c " & 'robocopy.exe ' & $sourcedir & ' ' & $destdir & " /TEE", @ScriptDir, @SW_Hide, 2 ) $output = "" $switch = 0; We don't want to run StringRegExp on lines that don't matter to us While ProcessExists($copyjob) $tempOutput = StdoutRead($copyjob , False , False) If not $tempOutput = "" Then $output = $tempOutput $output = StringSplit($output, @CRLF) For $i = 1 To $output[0] - 1 If Not $switch Then If StringRegExp($output[$i], '\d+\s+' & StringReplace($sourcedir, "\", "\\")) == 1 Then $switch = Not $switch $i += 1 EndIf EndIf If $switch Then $result = StringRegExp($output[$i], '([0-9.]+%)|([0-9.]+\s*[mg]?)\s*(.*)', 1) If IsArray($result) Then If StringInStr($result[0], "%") Then; Current line is a progress update line ; Set current progress bar to StringTrimRight($result[0], 1) GUICtrlSetData($progress, StringTrimRight($result[0], 1)) ; Set current progress percent label to $result[0] Else; Current line is a new file line ; Reset progress bar to 0 GUICtrlSetData($progress, 0) ; Reset progress percent label to "0%" ; Set current file size label to $result[0] (either a number in bytes or something like (4.2 m) GUICtrlSetData($sizeLbl, $result[1]) ; Set current file name label to $result[1] (outputted as filename) GUICtrlSetData($fileLbl, $result[2]) EndIf EndIf EndIf Next $output = $output[$output[0]] EndIf WEnd ; Do one more in case there's any output left in the stream after the $copyjob closes If StdoutRead($copyjob, 0, true) > 0 Then $output &= StdoutRead($copyjob) If StringInStr($output, @CRLF) Then $output = StringSplit($output, @CRLF) For $i = 1 To $output[0] If Not $switch Then If StringRegExp($output[$i], '\d+\s+' & StringReplace($sourcedir, "\", "\\")) Then $switch = Not $switch $i += 1 EndIf EndIf If $switch Then $result = StringRegExp($output[$i], '([0-9.]+%)|([0-9.]+\s*[mg]?)\s*(.*)', 1) If IsArray($result) Then If StringInStr($result[0], "%") Then; Current line is a progress update line ; Set current progress bar to StringTrimRight($result[0], 1) GUICtrlSetData($progress, StringTrimRight($result[0], 1)) ; Set current progress percent label to $result[0] Else; Current line is a new file line ; Reset progress bar to 0 GUICtrlSetData($progress, 0) ; Reset progress percent label to "0%" ; Set current file size label to $result[0] (either a number in bytes or something like (4.2 m) GUICtrlSetData($sizeLbl, $result[1]) ; Set current file name label to $result[1] (outputted as full filepath) GUICtrlSetData($fileLbl, $result[2]) EndIf EndIf EndIf Next EndIf EndIf EndFunc 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