Jump to content

Yet Another Copy with Progress Bar (need suggestions)


probedrone
 Share

Recommended Posts

Got the basic idea off Jdeb.

Usage:

_FileCopy("C:\start", "C:\dest") ; copies all files in start to dest

_FileCopy("C:\start\test.txt", "C:\dest") ; copies the file test.txt to dest

_FileCopy("C:\start", "C:dest", 1) ; copies the entire directory start into dest

_FileCopy("C:\start", "C:\dest", 0, "*.txt") ; copies all text files in start to dest

(Files will be overwritten)

Func _FileCopy($fromDir, $toDir, $copyDir=0, $wildCard = "*.*")
    If DirCreate($toDir) = 0 Then 
        Msgbox(0, "ERROR", $toDir & @LF & "Directory cannot be created.")
        Return
    EndIf

    Local $FOF_RESPOND_YES = 16
    $winShell = ObjCreate("Shell.Application")
    $objFolder = $winShell.namespace($toDir)
    
;Copies all files in a directory
    If StringInStr(FileGetAttrib($fromDir), "D") and $copyDir = 0 Then
; Shows the filenames of all files in the current directory.
        If StringRight($fromDir, 1) <> "\" Then $fromDir &= "\"
        $search = FileFindFirstFile($fromDir & $wildCard)
; Check if the search was successful
        If $search = -1 Then
            MsgBox(0, "Error", "No files/directories matched the search pattern")
            Return
        EndIf
; Start copy each file
        While 1
            $file = $fromDir & FileFindNextFile($search)
            If @error Then ExitLoop
            $objFolder.CopyHere($file, $FOF_RESPOND_YES)
        WEnd
        FileClose($search)
;Copies Singles files or directories
    Else
        $objFolder.CopyHere($fromDir, $FOF_RESPOND_YES)
    EndIf
EndFunc

Basically I used the windows shell app to create the progress bar. The thing is that it does not support wildcards, so I had to use autoit to seperate each file for it to copy all files in a folder over to another. If anyone can think of a way to copy the contents of a folder to another without using wildcards THEN BY ALL MEANS POST IT HERE! Other suggestions welcome too! :P

Edited by probedrone
Link to comment
Share on other sites

search in scrips and scraps for ezzetabi, and find his post called "copy with progress dialog". I used that to hand back the name of each file being copied. My progress bar was 0 at 1 file, and 100 at last file, with each successful copy incrementing the bar. I know for certain I got it to pass back each file name, which I think is what you want. However, I did have to tweak it a bit for my needs.

late,

Sul

Link to comment
Share on other sites

Got the basic idea off Jdeb.

Usage:

_FileCopy("C:\start", "C:\dest") ; copies all files in start to dest

_FileCopy("C:\start\test.txt", "C:\dest") ; copies the file test.txt to dest

_FileCopy("C:\start", "C:dest", 1) ; copies the entire directory start into dest

_FileCopy("C:\start", "C:\dest", 0, "*.txt") ; copies all text files in start to dest

(Files will be overwritten)

Basically I used the windows shell app to create the progress bar. The thing is that it does not support wildcards, so I had to use autoit to seperate each file for it to copy all files in a folder over to another. If anyone can think of a way to copy the contents of a folder to another without using wildcards THEN BY ALL MEANS POST IT HERE! Other suggestions welcome too! :)

You can use/butcher this

;use ProgressCopy(Source,Destination, 1 to use multi colour ,"Attributes", 1 for Overwrite files)
#include <GUIConstants.au3>
ProgressCopy("D:\Images", "d:\Backup\",1) 

Func ProgressCopy($current, $destination,  $UseMultiColour=0, $attrib = "-R", $overwrite = 1 ,$Run1 = 0 )
    
;FirstTimeRun Get original DirSize and set up Gui
    If $Run1 = 0 Then
        Global $OverallQty, $Overall, $source, $overallpercent, $Progress0Text, $progressbar1, $Progress1Text, $progressbar2, $Progress2Text,  $LocalPercent
        DllCall("uxtheme.dll", "none", "SetThemeAppProperties", "int", 0)
        If not FileExists ($Destination) then DirCreate ($Destination); This is why it was failing, the dir did not exist
        $source = $current
        If StringRight($current, 1) = '\' Then $current = StringTrimRight($current, 1)
        If StringRight($destination, 1) <> '\' Then $destination = $destination & "\"
        $tosearch = $current
        $Overall = DirGetSize($tosearch, 1)
        $OverallQty = $Overall[1]
        Global Const $PrCopyGui = GUICreate("Copying Files", 420, 100, -1, -1, -1, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
        $Progress0Text = GUICtrlCreateLabel("Please Wait", 10, 5, 400, 20, $SS_LEFTNOWORDWRAP)
        $progressbar1 = GUICtrlCreateProgress(10, 20, 400, 20)
        GUICtrlSetColor(-1, 32250)
        $Progress1Text = GUICtrlCreateLabel("", 10, 44, 400, 20, $SS_LEFTNOWORDWRAP)
        $progressbar2 = GUICtrlCreateProgress(10, 60, 400, 20, $PBS_SMOOTH)
        $Progress2Text = GUICtrlCreateLabel("", 10, 82, 400, 20, $SS_LEFTNOWORDWRAP)
        GUISetFont(10, 600)
    ;$Progress2Text2 = GUICtrlCreateLabel("", 150, 62, 400, 20)
        GUICtrlSetColor(-1, 32250); not working with Windows XP Style if not using windows classic style or dllcall above
        GUISetState(@SW_SHOW)
        GUICtrlSetData($Progress1Text, "Working Directory " & $tosearch)
        $Run1 = 1
    EndIf
    
    $Size = DirGetSize($current, 3)
    $Qty = $Size[1]
    Local $search = FileFindFirstFile($current & "\*.*")
    While 1
        Dim $file = FileFindNextFile($search)
        If @error Or StringLen($file) < 1 Then ExitLoop
        If Not StringInStr(FileGetAttrib($current & "\" & $file), "D") And ($file <> "." Or $file <> "..") Then
            $Qty -= 1
            $LocalPercent = 100 - (($Qty / $Size[1]) * 100)
            $OverallQty -= 1
            $overallpercent = 100 - (($OverallQty / $Overall[1]) * 100)
            GUICtrlSetData($Progress0Text, "Total Progress " & Int($overallpercent) & "% completed")
            GUICtrlSetData($progressbar1, $overallpercent)
            GUICtrlSetData($progressbar2, $LocalPercent)
            GUICtrlSetData($Progress2Text, "Copying File " & $file)
            
            If $useMultiColour then 
                GUICtrlSetColor($Progressbar2, _ChangeColour($LocalPercent))
                GUICtrlSetColor($Progressbar1, _ChangeColour($OverallPercent))
            EndIf
            
            FileCopy($current & "\" & $file, $destination & StringTrimLeft($current, StringLen($source)) & "\" & $file,$overwrite)
            FileSetAttrib($destination & StringTrimLeft($current, StringLen($source)) & "\" & $file, $attrib)
        EndIf
        If StringInStr(FileGetAttrib($current & "\" & $file), "D") And ($file <> "." Or $file <> "..") Then
            DirCreate($destination & StringTrimLeft($current, StringLen($source)) & "\" & $file)
            FileSetAttrib($destination & StringTrimLeft($current, StringLen($source)) & "\" & $file, $attrib)
            GUICtrlSetData($Progress1Text, $current & "\" & $file)
            ProgressCopy($current & "\" & $file, $destination, $UseMultiColour, $attrib, $overwrite,1)
        EndIf
    WEnd
    FileClose($search)
;when overall percent = 100 set end gui text, delete gui and reset run1 to 0
    If $overallpercent = 100 Then
        GUICtrlSetData($Progress0Text, "Total Progress 100% completed")
        GUICtrlSetData($progressbar1, 100)
        GUICtrlSetData($progressbar2, 100)
        GUICtrlSetData($Progress2Text, "Done!")
        Sleep(2000)
        GUIDelete($PRCopyGui)
        $Run1 = 0
    EndIf
EndFunc  ;==>ProgressCopy

Func _ChangeColour($start)
    
    $Redness = Int(255 - ($start  / 100 * 512)) 
    If $Redness < 0 Then $Redness = 0
        
    $Greeness = Int(($start  / 100 * 512) - 257) 
    If $Greeness < 0 Then $Greeness = 0
        
    $Blueness = Int(255 - ($Redness + $Greeness))
    
    Return ($Redness * 256 * 256) + ($Greeness * 256) + $Blueness

EndFunc

Or Larry I think did this one

Global Const $FO_MOVE                  = 0x0001
Global Const $FO_COPY                  = 0x0002
Global Const $FO_DELETE              = 0x0003
Global Const $FO_RENAME              = 0x0004

Global Const $FOF_MULTIDESTFILES        = 0x0001
Global Const $FOF_CONFIRMMOUSE        = 0x0002
Global Const $FOF_SILENT                = 0x0004
Global Const $FOF_RENAMEONCOLLISION  = 0x0008
Global Const $FOF_NOCONFIRMATION        = 0x0010
Global Const $FOF_WANTMAPPINGHANDLE  = 0x0020
Global Const $FOF_ALLOWUNDO          = 0x0040
Global Const $FOF_FILESONLY          = 0x0080
Global Const $FOF_SIMPLEPROGRESS        = 0x0100
Global Const $FOF_NOCONFIRMMKDIR        = 0x0200
Global Const $FOF_NOERRORUI          = 0x0400
Global Const $FOF_NOCOPYSECURITYATTRIBS = 0x0800
Global Const $FOF_NORECURSION          = 0x1000
Global Const $FOF_NO_CONNECTED_ELEMENTS = 0x2000
Global Const $FOF_WANTNUKEWARNING      = 0x4000
Global Const $FOF_NORECURSEREPARSE    = 0x8000

Dim $n


$n = _CopyWithProgress("D:\images" , "D:\Backup")

Func _CopyWithProgress($sFrom, $sTo)
    Local $SHFILEOPSTRUCT
    Local $pFrom
    Local $pTo
    Local $aDllRet
    Local $nError = 0
    Local $i
    
    $SHFILEOPSTRUCT = DllStructCreate("int;uint;ptr;ptr;uint;int;ptr;ptr")
    If @error Then Return False     
; hwnd
    DllStructSetData($SHFILEOPSTRUCT, 1, 0)
; wFunc
    DllStructSetData($SHFILEOPSTRUCT, 2, $FO_COPY)
; pFrom
    $pFrom = DllStructCreate("char[" & StringLen($sFrom)+2 & "]")
; pFrom will now be null-terminated at StringLen($sFrom)+1
    DllStructSetData($pFrom, 1, $sFrom)
    For $i = 1 To StringLen($sFrom)+2
        If DllStructGetData($pFrom, 1, $i) = 10 Then DllStructSetData($pFrom, 1, 0, $i)
    Next
; We need a second null at the end
    DllStructSetData($pFrom, 1, 0, StringLen($sFrom)+2)
    DllStructSetData($SHFILEOPSTRUCT, 3, DllStructGetPtr($pFrom))
; pTo
    $pTo = DllStructCreate("char[" & StringLen($sTo)+2 & "]")
; pTo will now be null-terminated at StringLen($sTo)+1
    DllStructSetData($pTo, 1, $sTo)
; We need a second null at the end
    DllStructSetData($pTo, 1, 0, StringLen($sTo)+2)
    DllStructSetData($SHFILEOPSTRUCT, 4, DllStructGetPtr($pTo))
; fFlags
    DllStructSetData($SHFILEOPSTRUCT, 5, BitOR($FOF_NOCONFIRMMKDIR, _ 
        $FOF_NOCONFIRMATION, _ 
        $FOF_NOERRORUI))
; fAnyOperationsAborted
    DllStructSetData($SHFILEOPSTRUCT, 6, 0)
; hNameMappings
    DllStructSetData($SHFILEOPSTRUCT, 7, 0)
; lpszProgressTitle
    DllStructSetData($SHFILEOPSTRUCT, 8, 0)
    $aDllRet = DllCall("shell32.dll", "int", "SHFileOperation", "ptr", DllStructGetPtr($SHFILEOPSTRUCT))
    If @error Or $aDllRet[0] <> 0 Then
        $aDllRet = DllCall("kernel32.dll", "long", "GetLastError")
        If Not @error Then $nError = $aDllRet[0]
        EndIf
        $pForm=0
        $pto=0
        $SHFILEOPSTRUCT=0
 ;DllStructDelete($pFrom)
; DllStructDelete($pTo)
 ;DllStructDelete($SHFILEOPSTRUCT)
    If $nError <> 0 Then 
        SetError($nError)
        Return False
    EndIf
    Return True
EndFunc
Edited by ChrisL
Link to comment
Share on other sites

  • 2 months later...

hey chrisl , i liked the ProgressCopy script

can you help me with somethink ?

is there any way to stop the copying of files? ? (i have put the script into a window with 2 button , start and stop , but i can't figure out how can i stop the copying, exen the X doesn't work)

thans in advance

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...