Sign in to follow this  
Followers 0
gcue

Teracopy in Autoit

4 posts in this topic

#1 ·  Posted (edited)

for those of you who arent familiar with teracopy? its a utility that queues files for copying or moving.

i wish it had a few more options so i want to try to build my own.

not sure if i can PAUSE/SKIP/CANCEL transfers though since Autoit does not support multi-threading

any creative ways anyone can think of around this?

or has anyone had a shot at this?

Edited by gcue

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

for those of you who arent familiar with teracopy? its a utility that queues files for copying or moving.

i wish it had a few more options so i want to try to build my own.

not sure if i can PAUSE/SKIP/CANCEL transfers though since Autoit does not support multi-threading

any creative ways anyone can think of around this?

or has anyone had a shot at this?

Here is my sync tool, sounds similar. The STOP only gets checked between transfers, so it will not pause a transfer in progress, but maybe if it were polled in the __Progress function it might, though that could slow it down A LOT which is why I never even tried it. Otherwise I am having issues with the GUI freezing on transfers once they hit about 150MB copied, have tried TOO MANY things to fix it and have come up short, but I like the main function of the script. I'd love thoughts on the GUI issue and any other suggestions.

#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 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)&"%")
                GUICtrlSetData($totalslide,$donesofar / $size * 100)
            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

Ian

Edited 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.

Share this post


Link to post
Share on other sites

for those of you who arent familiar with teracopy? its a utility that queues files for copying or moving.

i wish it had a few more options so i want to try to build my own.

not sure if i can PAUSE/SKIP/CANCEL transfers though since Autoit does not support multi-threading

any creative ways anyone can think of around this?

or has anyone had a shot at this?

AutoIT supports FileCopy, Delete, Move. Open. There are plenty code snippets that will get you started. You can write code to pause skip or cancel all of which is covered in Help.

This is some code which I use to manage Nil user activity which you can put inside a Loop statement like 'While 1' 'WEnd'

_UserGui()

;//Exit Menu After nn Minutes Nil Activity
Func _UserGui()
    While 1
        ;//Start the Timer
        $MenuCycle = _TimeToTicks(@HOUR, @MIN, @SEC)
        $MenuEndCycle = $MenuCycle + $EndMenuTimer * 60 * 1000
        ;//Create the User Interface
        GUICreate("YourGui", 365, 295, -1, -1)
        GUISetBkColor(0xE0FFFF)
        GUISetState()   
        ;//Exit the Application
        $sExit = GUICtrlCreateButton("Close", 265, 260, 70, 25)
        ;//Create a User Control for Each Process
        While 1
            ;//Exit after nn Minutes
            If _TimeToTicks(@HOUR, @MIN, @SEC) >= $MenuEndCycle Then
                GUIDelete()
                ExitLoop (2)
            EndIf
            ;//Check for User Input
            Select
                ;//Exit the Application
                Case $msg = $GUI_EVENT_CLOSE Or $msg = $sExit
                    GUIDelete()
                    $SysMessage = "Report Generator CLOSED"
                    ;//Write the System and Admin Record
                    _RecordIdProcessor(2, 4)
                    ExitLoop (2)
                Case $msg = ;//Name for the Process
                    ;//Create a Case for Each Process               
            EndSelect           
        WEnd
    WEnd
EndFunc

Share this post


Link to post
Share on other sites

thanks llewxam - but ya id be nice to cancel/pause/skip anytime.

thanks anixon - still unclear to me what you mean.

Share this post


Link to post
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
Sign in to follow this  
Followers 0