zdarma Posted February 8, 2011 Share Posted February 8, 2011 I'm a noob to the world of AutoIT,. I've searched the web and searched the forums on this site, but have not found something that corresponds to my problem. I have a script that copies files or folders to multiple machines at the same time. I pre-set the number of machines to copy too launch simultaneously in an INI file. This works without a problem. I have a function that is supposed to show the progress for each individual copy that is being done. This is where things seem to get a bit tricky. This is the copy section that calls the function progress GUI: For $copie = 1 to $aMagCopie[0] $aMagasinsChoisi = StringSplit($aMagCopie[$copie], ";") run("NET USE \\" & $aMagasinsChoisi[5] & "\d$ /PERSISTENT:NO /USER:" & $sLogin & " " & $sMdp) $sDestinationPlace = '"\\' & $aMagasinsChoisi[5] & $sFichiersDest & "\" & $sDossierVerif[$iDossierCreation - 1] &'"' Run($sRobocopyCmd & " " & '"' & $sFichierSource & '"' & " " & $sDestinationPlace & " /MIR /R:0 /W:0 /FFT /TEE /LOG:Robocopy_" & $aMagasinsChoisi[1] & "_" & $iDateCopie & ".log") _Progress($sFichierSource, $aMagasinsChoisi[1], $sDestinationPlace) While 1 $aProcRobocopy = ProcessList("robocopy.exe") If $aProcRobocopy[0][0] < $iMaxCopie Then ExitLoop Sleep(500) WEnd Next This is my GUI progress fucntion expandcollapse popupFunc _Progress($sSource, $sNomMagasin, $sDestination) Global $iGetFicherTaille = StringReplace($sDestination,'"',"") Global $iCopierPourcent = 0 Global $checkadvance = 0 GUICreate("Progress de la copie pour " & $sNomMagasin, 290, 150, 300, 115) ;Creation de la formulaire GUICtrlCreateLabel("Pourcentage de la copie fait pour " & @CRLF & $sNomMagasin, 20, 10, 390, 41) GUICtrlSetFont(-1, 10, 400, 0, "MS Sans Serif") Global $oBarAvance1 = GUICtrlCreateProgress(20, 75, 250, 15) ;bar de progression GUISetState(@SW_SHOW) If $sFichierTypes = "File" Then $iFichierOrigin = FileGetSize($sSource) While $iCopierPourcent <= 100 $iFichierCopied = FileGetSize($iGetFicherTaille) $iCopierPourcent = Round((($iFichierCopied / $iFichierOrigin) * 100), 0) If $iCopierPourcent > $checkadvance Then GUICtrlSetData($oBarAvance1, $iCopierPourcent) $spercentEcrit = GUICtrlCreateLabel($iCopierPourcent & "% de la copie est terminée", 20, 125, 250, 15) EndIf Return $checkadvance = $iCopierPourcent WEnd Else $iFichierOrigin = DirGetSize($sSource) While $iCopierPourcent <= 100 $iFichierCopied = DirGetSize($iGetFicherTaille) $iCopierPourcent = Round((($iFichierCopied / $iFichierOrigin) * 100), 0) If $iCopierPourcent > $checkadvance Then GUICtrlSetData($oBarAvance1, $iCopierPourcent) $spercentEcrit = GUICtrlCreateLabel($iCopierPourcent & "% de la copie est terminée", 20, 125, 250, 15) EndIf $checkadvance = $iCopierPourcent If $iCopierPourcent >= 100 Then GUISetState(@SW_HIDE) MsgBox(64, "Copie terminé", "La copie est terminé pour" & @CRLF & $sNomMagasin) ExitLoop EndIf Return WEnd EndIf EndFunc If I remove the "return", my script will only do one copy at a time showing me the progress of the copy being done. Once the copy is done for a machine, it will proceed to the next and create a new GUI progress bar for me. If I leave the "return", my script will open up an individual advancement GUI for each copy being done, but will not update the progress at all; but will proceed with the maximum number of copies I've pre-set in my INI file, without showing any advancement. I've tried putting the GUI progress bar directly in the part of my script that does the copy, but I still run into the same problem. I've tried to create my GUI progress bar as a script and pass the parameters to the script, but for some reason AutoIT doesn't seem to like that any more than the way I have it set up now. Does any one have an idea how I can get a work around. If needed, I can post my entire script or clear up anything that isn't clear. Link to comment Share on other sites More sharing options...
PsaltyDS Posted February 8, 2011 Share Posted February 8, 2011 You should be catching all the PIDs from Run() in an array, creating a progress for each of them and tracking those in an a matching array (or keep both in a 2D array together). While you wait for them to run your loop will update each progress bar for each PID by walking through the array(s). Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
zdarma Posted February 9, 2011 Author Share Posted February 9, 2011 You should be catching all the PIDs from Run() in an array, creating a progress for each of them and tracking those in an a matching array (or keep both in a 2D array together). While you wait for them to run your loop will update each progress bar for each PID by walking through the array(s).Thanks for the pointer.Just to be clear, I should use the Run PIDs from the Robocopy.exe ? I am catching those PIDs already to check for number of simultaneous copies running and could use them to loop for each progress bar I need. Link to comment Share on other sites More sharing options...
PsaltyDS Posted February 9, 2011 Share Posted February 9, 2011 Maybe I didn't understand your question. You will have multiple instances of robocopy running at once, right? Did you want a progress bar for each instance, or one progress bar reflecting total progress of all instances? Either way, you have to poll all the instances of robocopy at regular intervals to either get individual progress or create the total progress. You don't necessarily need the PID to do that, it depends on your method for checking current progress of each copy. Your GUI needs to be created outside the _Progress() function call. The function should only be updating the GUI, not creating a new one for each copy if you want multiple copies running at once and only one GUI reporting on them. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
zdarma Posted February 9, 2011 Author Share Posted February 9, 2011 (edited) Maybe I didn't understand your question. You will have multiple instances of robocopy running at once, right? Did you want a progress bar for each instance, or one progress bar reflecting total progress of all instances? Either way, you have to poll all the instances of robocopy at regular intervals to either get individual progress or create the total progress. You don't necessarily need the PID to do that, it depends on your method for checking current progress of each copy. Your GUI needs to be created outside the _Progress() function call. The function should only be updating the GUI, not creating a new one for each copy if you want multiple copies running at once and only one GUI reporting on them. No worries, if you didn't understand my question. If needed, I can upload my entire script when I get into the office tomorrow and maybe that will make things a little clearer. I have multiple instances of robocopy running and need a progress bar for each instance. I may need to copy a file or folder to 20 machines, but only 5 will be getting the copy at the same time. As soon as one robocopy is finished, the next machine begins to copy. I'm already checking the number of robocpies running in my script by looking at the value in $aArray[0][0] from ProcessList("robocopy.exe"). Once a copy has finished, I need a message sent that Machine X is done. Then, start copying the next machine in the list and create a new progress bar for the new robocpy instance. My method for checking the progress done, is by comparing the size of the source to the destination, I do a ((destination/source) * 100) to get the percentage done. It is this number that I use to get the progress bar to advance X number of spaces forward. Do I still need to create the GUI outside of the _Progress() function call if I want multiple progress bars. If so, do I need to create a function called for example _ProgressGUI() and send the data from _Progress() to _ProgressGUI()? Edited February 9, 2011 by zdarma Link to comment Share on other sites More sharing options...
PsaltyDS Posted February 10, 2011 Share Posted February 10, 2011 Yes, create the GUI once and just create/update/delete the progress bars as required during the updates. Here is a working simulation: expandcollapse popup#include <GuiConstants.au3> #include <Array.au3> Opt("GuiOnEventMode", 1) Global $iSourceSize = 1234 ; Simulated source size Global $iTargets = 20 ; Count of targets Global $aTargets[$iTargets] For $n = 0 To UBound($aTargets) - 1 $aTargets[$n] = "Target_" & $n Next Global $hGUI Global $aidProgBars[5] = [-1, -1, -1, -1, -1], $aidLabels[5], $aProgress[5] $hGUI = GUICreate("Multi-Robo", 400, 385) GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit") GUISetState() While 1 _UpdateProgBars() _UpdateProgress() Sleep(250) WEnd Func _UpdateProgBars() Local $f_DoneCheck = True ; Check the progress bar slots For $n = 0 To UBound($aidProgBars) - 1 If $aidProgBars[$n] = -1 Then ; Unused progress spot If IsArray($aTargets) Then $f_DoneCheck = False ; Not done if there are any new targets left $aidLabels[$n] = GUICtrlCreateLabel($aTargets[0], 10, 10 + ($n * 75), 380, 15) $aidProgBars[$n] = GUICtrlCreateProgress(10, 25 + ($n * 75), 380, 50) $aProgress[$n] = 0 _ArrayDelete($aTargets, 0) EndIf Else $f_DoneCheck = False ; Not done if there are any active progress bars left If $aProgress[$n] >= $iSourceSize Then ; Finished progress spot GUICtrlDelete($aidLabels[$n]) GUICtrlDelete($aidProgBars[$n]) $aidProgBars[$n] = -1 EndIf EndIf Next If $f_DoneCheck Then MsgBox(64, "Multi-Robo", "Done") Exit EndIf EndFunc ;==>_UpdateProgBars Func _UpdateProgress() For $n = 0 To UBound($aidProgBars) - 1 If $aidProgBars[$n] <> -1 Then ; Simulated progress If $aProgress[$n] < $iSourceSize Then $aProgress[$n] += Random(10, 100, 1) If $aProgress[$n] > $iSourceSize Then $aProgress[$n] = $iSourceSize ; Update the GUI GUICtrlSetData($aidProgBars[$n], $aProgress[$n] / $iSourceSize * 100) EndIf Next EndFunc ;==>_UpdateProgress Func _Quit() Exit EndFunc ;==>_Quit Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
zdarma Posted February 10, 2011 Author Share Posted February 10, 2011 PsaltyDS, thanks for the snippet. I took a look at it and it does exactly what I wanted to happen. I'm going to try and integrate it into my script now. Youùll know when its done when you see me in the streets. 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