darbid Posted August 11, 2008 Share Posted August 11, 2008 I am unable to get my mind around progress bars, which actually reflect the progress of my event. I am doing an "install" - a copy of a directory from a network (access could be at varied speeds - thus the need to show actual progress and not some timed progress bar) I have found many snippets and exmples of file progress bars using file copy and arrays but not much on a directory. I also have my own eyecandy PNG gui (which I am very chuffed about) so just want to add a progress bar to that and not use a standard windows window. Could somebody link me to an example which WORKS, that I can then read, understand and convert for my own needs. I am sure there are loads of examples. Link to comment Share on other sites More sharing options...
smashly Posted August 11, 2008 Share Posted August 11, 2008 Hi, Bottom line is if you want to copy a directory that contains other directories and files and you want a semi accurate progress bar then do a recursive filelist to array of the directory, loop through the array copying each file/folder and set the progress bar a step each time a file/folder copies. Cheers Link to comment Share on other sites More sharing options...
darbid Posted August 11, 2008 Author Share Posted August 11, 2008 and would your answer change if there are no sub folders?semi accurate progress bar then do a recursive filelist to array of the directory, loop through the array copying each file/folder and set the progress bar a step each time a file/folder copies.and has someone ever posted an example of this here. Link to comment Share on other sites More sharing options...
ofLight Posted August 11, 2008 Share Posted August 11, 2008 This will handle sub directorys if needed. Alot of the _DirCopy func was hardcoded for my personal use, but could easily be adapted to update a global Progressbar. expandcollapse popup#include <WindowsConstants.au3> #include <GUIConstantsEX.au3> #include <ProgressConstants.au3> _DirCopy("c:\DRV","c:\DRV2") ;example use ;=============================================================================== ; Function Name: _DirCopy ; Description: ; Requires: GUIConstantsEx.au3, WindowsConstants.au3, ProgressConstants.au3 ; must set $Progress_ControlID as Global ; Parameters: $Source Source Directory to Copy from ; $Dest Destination directory to copy to ; Syntax: _DirCopy($Source,$Dest) ; Author(s): ofLight ; Returns: ;=============================================================================== Func _DirCopy($Source,$Dest) If WinExists('GUI_RobocopyProgress') Then GUICtrlSetState($Progress_ControlID,0) GUISetState(@SW_SHOW,$GUI_RS_DirCopy) ;GUISetState(@SW_SHOW,$Progress_ControlID) ;WTF is up with THIS>?!? $Progress_ControlID = GUICtrlCreateProgress(10, 5, 380, 20, $PBS_SMOOTH) GUISetState(@SW_SHOW) Else $GUI_RS_DirCopy = GUICreate('GUI_RobocopyProgress',400,40, -1, (@DesktopHeight/2)+70, BitOR($WS_POPUP, $WS_BORDER)) GUISetBkColor(16777215) $Progress_ControlID = GUICtrlCreateProgress(10, 5, 380, 20, $PBS_SMOOTH) $Progress_LabelID = GUICtrlCreateLabel("",10,25,380) GUISetBkColor(16777215) GUISetState(@SW_SHOW) EndIf If $Source <> "" Then _SUB_CopyDirWithProgress($Source, $Dest, $Progress_ControlID,$Progress_LabelID) GUICtrlSetState($Progress_ControlID,100) Sleep(50) GUISetState(@SW_HIDE,$GUI_RS_DirCopy) EndFunc Func _SUB_CopyDirWithProgress($sOriginalDir, $sDestDir, $Progress_ControlID, $Label_ControlID);SUB Function of _DirCopy If StringRight($sOriginalDir, 1) <> '\' Then $sOriginalDir = $sOriginalDir & '\' If StringRight($sDestDir, 1) <> '\' Then $sDestDir = $sDestDir & '\' If $sOriginalDir = $sDestDir Then Return -1 ;ProgressOn('Copying...', 'Making list of files...' & @LF & @LF, '', -1, -1, 18) Local $aFileList = _SUB_FileSearch($sOriginalDir) If $aFileList[0] = 0 Then ;ProgressOff() SetError(1) Return -1 EndIf If FileExists($sDestDir) Then If Not StringInStr(FileGetAttrib($sDestDir), 'd') Then ;ProgressOff() SetError(2) Return -1 EndIf Else DirCreate($sDestDir) If Not FileExists($sDestDir) Then ;ProgressOff() SetError(2) Return -1 EndIf EndIf Local $iDirSize, $iCopiedSize = 0, $fProgress = 0 Local $c, $FileName, $iOutPut = 0, $sLost = '', $sError Local $Sl = StringLen($sOriginalDir) _SUB_Quick_Sort($aFileList, 1, $aFileList[0]) $iDirSize = Int(DirGetSize($sOriginalDir) / 1024) GUICtrlSetData($Progress_ControlID,Int($fProgress * 100)) GUICtrlSetData($Label_ControlID,$aFileList[$c]) For $c = 1 To $aFileList[0] $FileName = StringTrimLeft($aFileList[$c], $Sl) GUICtrlSetData($Progress_ControlID,Int($fProgress * 100)) GUICtrlSetData($Label_ControlID, 'Total: '&$iDirSize&'Kb --> Done: '&$iCopiedSize&'Kb '&StringTrimLeft($aFileList[$c],StringInStr($aFileList[$c],"\",0,-1))) If StringInStr(FileGetAttrib($aFileList[$c]), 'd') Then DirCreate($sDestDir & $FileName) Else If Not FileCopy($aFileList[$c], $sDestDir & $FileName, 1) Then If Not FileCopy($aFileList[$c], $sDestDir & $FileName, 1) Then;Tries a second time If RunWait(@ComSpec & ' /c copy /y "' & $aFileList[$c] & '" "' & $sDestDir & $FileName & '">' & @TempDir & '\o.tmp', '', @SW_HIDE) = 1 Then;and a third time, but this time it takes the error message $sError = FileReadLine(@TempDir & '\o.tmp', 1) $iOutPut = $iOutPut + 1 $sLost = $sLost & $aFileList[$c] & ' ' & $sError & @CRLF EndIf FileDelete(@TempDir & '\o.tmp') EndIf EndIf FileSetAttrib($sDestDir & $FileName, "+A-RSH");<- Comment this line if you do not want attribs reset. $iCopiedSize = $iCopiedSize + Int(FileGetSize($aFileList[$c]) / 1024) $fProgress = $iCopiedSize / $iDirSize EndIf Next If $sLost <> '' Then;tries to write the log somewhere. If FileWrite($sDestDir & 'notcopied.txt', $sLost) = 0 Then If FileWrite($sOriginalDir & 'notcopied.txt', $sLost) = 0 Then FileWrite(@WorkingDir & '\notcopied.txt', $sLost) EndIf EndIf EndIf Return $iOutPut EndFunc ;==>_CopyDirWithProgress Func _SUB_FileSearch($sIstr, $bSF = 1);SUB Function of _DirCopy ; $bSF = 1 means looking in subfolders ; $sSF = 0 means looking only in the current folder. ; An array is returned with the full path of all files found. The pos [0] keeps the number of elements. Local $sCriteria, $sBuffer, $iH, $iH2, $sCS, $sCF, $sCF2, $sCP, $sFP, $sOutPut = '', $aNull[1] ;Local $sIstr, $bSF, $sCriteria, $sBuffer, $iH, $iH2, $sCS, $sCF, $sCF2, $sCP, $sFP, $sOutPut = '', $aNull[1] $sCP = StringLeft($sIstr, StringInStr($sIstr, '\', 0, -1)) If $sCP = '' Then $sCP = @WorkingDir & '\' $sCriteria = StringTrimLeft($sIstr, StringInStr($sIstr, '\', 0, -1)) If $sCriteria = '' Then $sCriteria = '*.*' ;To begin we seek in the starting path. $sCS = FileFindFirstFile($sCP & $sCriteria) If $sCS <> -1 Then Do $sCF = FileFindNextFile($sCS) If @error Then FileClose($sCS) ExitLoop EndIf If $sCF = '.' Or $sCF = '..' Then ContinueLoop $sOutPut = $sOutPut & $sCP & $sCF & @LF Until 0 EndIf ;And after, if needed, in the rest of the folders. If $bSF = 1 Then $sBuffer = @CR & $sCP & '*' & @LF;The buffer is set for keeping the given path plus a *. Do $sCS = StringTrimLeft(StringLeft($sBuffer, StringInStr($sBuffer, @LF, 0, 1) - 1), 1);current search. $sCP = StringLeft($sCS, StringInStr($sCS, '\', 0, -1));Current search path. $iH = FileFindFirstFile($sCS) If $iH <> -1 Then Do $sCF = FileFindNextFile($iH) If @error Then FileClose($iH) ExitLoop EndIf If $sCF = '.' Or $sCF = '..' Then ContinueLoop If StringInStr(FileGetAttrib($sCP & $sCF), 'd') Then $sBuffer = @CR & $sCP & $sCF & '\*' & @LF & $sBuffer;Every folder found is added in the begin of buffer $sFP = $sCP & $sCF & '\'; for future searches $iH2 = FileFindFirstFile($sFP & $sCriteria); and checked with the criteria. If $iH2 <> -1 Then Do $sCF2 = FileFindNextFile($iH2) If @error Then FileClose($iH2) ExitLoop EndIf If $sCF2 = '.' Or $sCF2 = '..' Then ContinueLoop $sOutPut = $sOutPut & $sFP & $sCF2 & @LF;Found items are put in the Output. Until 0 EndIf EndIf Until 0 EndIf $sBuffer = StringReplace($sBuffer, @CR & $sCS & @LF, '') Until $sBuffer = '' EndIf If $sOutPut = '' Then $aNull[0] = 0 Return $aNull Else Return StringSplit(StringTrimRight($sOutPut, 1), @LF) EndIf EndFunc ;==>_FileSearch Func _SUB_Quick_Sort(ByRef $SortArray, $First, $Last);Larry's code ;SUB Function of _DirCopy Dim $Low, $High Dim $Temp, $List_Separator $Low = $First $High = $Last $List_Separator = StringLen($SortArray[($First + $Last) / 2]) Do While (StringLen($SortArray[$Low]) < $List_Separator) $Low = $Low + 1 WEnd While (StringLen($SortArray[$High]) > $List_Separator) $High = $High - 1 WEnd If ($Low <= $High) Then $Temp = $SortArray[$Low] $SortArray[$Low] = $SortArray[$High] $SortArray[$High] = $Temp $Low = $Low + 1 $High = $High - 1 EndIf Until $Low > $High If ($First < $High) Then _SUB_Quick_Sort($SortArray, $First, $High) If ($Low < $Last) Then _SUB_Quick_Sort($SortArray, $Low, $Last) EndFunc ;==>_Quick_Sort There is always a butthead in the crowd, no matter how hard one tries to keep them out.......Volly Link to comment Share on other sites More sharing options...
darbid Posted August 11, 2008 Author Share Posted August 11, 2008 (edited) thanks oflight i will give it a go edit: that is not going to be as easy as I thought. I can copy directories, YEH YEH but that is the easy bit. As I am future planning what will be copied in these directories, but at the moment there is not much. This code really does not show progress if there are a small number of files in there, in fact with one file it showns none, but gets the job done. Edited August 11, 2008 by darbid Link to comment Share on other sites More sharing options...
ofLight Posted August 11, 2008 Share Posted August 11, 2008 You are correct, this process does not keep track of how much of each file has been copied over, only how many have been completed ( I couldn't find that info being piped out by the copy command). Because of this, copying 1 or 2 large files will not display smoothly. This process works best for directories with large quantities of files. There is always a butthead in the crowd, no matter how hard one tries to keep them out.......Volly Link to comment Share on other sites More sharing options...
darbid Posted August 11, 2008 Author Share Posted August 11, 2008 (edited) keeping in mind that I am an idiot and have no idea how these things work -Has anyone seen a progress bar where it somehow measures the size of the task (here size of files) at the beginning and then measures the amount copied as it is copied thus giving a % complete.for example this guys has used some other way ut sadly nothing is there. forum post Edited August 11, 2008 by darbid Link to comment Share on other sites More sharing options...
darbid Posted August 12, 2008 Author Share Posted August 12, 2008 So I have found this solution which uses a windows explorer windowWindows Explorer SolutionBut I too want to use my lovely GUI (with png background) that I have made and not go to a windows explorer window.The reason why you all stop short of coming to a solution (I THINK) is that the logical answer is to use a dirgetsize on source and destination, but because windows allocates the destiantion directory size straight away the progress bar show 100% straight away.eg problem with using dirgetsizeSo at the risk of asking the same question another way :-) has anyone found a solution to this, or maybe can someone see a possibility here to try something new? 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