Jump to content

Copy with progress dialog...


Recommended Posts

Guest Bilou_Gateux

Could some one post an AutoIT script to call the function from within a batch file (bat or cmd).

autoit3.exe filecopy.au3 source destination

Example

source=D:\AI\SOURCE\I386\ is the Command Line Parameter 1

destination=C:\I386\ is Command Line Parameter 2

values are passed to the function

_CopyDirWithProgress("D:\AI\SOURCE\I386\", "C:\I386\")

Edited by Bilou_Gateux
Link to post
Share on other sites
  • Replies 69
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

This code copies a folder content in an other folder that have to exist already. It shows a progress dialog with percent completed (calculed over size) and a fraction of action done (calculated with

Posted Images

Could some one post an AutoIT script to call the function from within a batch file (bat or cmd).

autoit3.exe filecopy.au3 source destination

Example

source=D:\AI\SOURCE\I386\ is the Command Line Parameter 1

destination=C:\I386\ is Command Line Parameter 2

values are passed to the function

_CopyDirWithProgress("D:\AI\SOURCE\I386\", "C:\I386\")

<{POST_SNAPBACK}>

Why all that work? Why not just use XCOPY? That will do recursive folders and even has an option to do hidden files/folders as well.
Link to post
Share on other sites

...I hate this kind of answers...

Why not use XXCopy? It permit also copying NTFS rights!

So? What? He asked something different!

just use $cmdline[]

if $cmdline[0] > 1 Then
  _CopyDirWithProgress($cmdline[1], $cmdline[2])
 ;Some error checking here
endif
Link to post
Share on other sites

...I hate this kind of answers...

Why not use XXCopy? It permit also copying NTFS rights!

So? What? He asked something different!

just use $cmdline[]

if $cmdline[0] > 1 Then
  _CopyDirWithProgress($cmdline[1], $cmdline[2])
;Some error checking here
endif

<{POST_SNAPBACK}>

He said he wanted a program to recursively copy files, and that he wanted to be able to call it on the command line. My question is why write your own program to do that when one already exists and is already available on every MS machine? It would reduce his development/debugging time as well as reduce the overall size of whatever he's distributing.
Link to post
Share on other sites

He said he wanted a program to recursively copy files, and that he wanted to be able to call it on the command line.  My question is why write your own program to do that when one already exists and is already available on every MS machine?  It would reduce his development/debugging time as well as reduce the overall size of whatever he's distributing.

<{POST_SNAPBACK}>

Simple... I want to have this progressbar. It looks very professional. I don't like having a dos window popping up... and I don't want to just hide the dos window and not show progress. I allready know how to use xcopy... and that is the idea... I want to be able to basically do what xcopy does... but with ezzetabi's progressbar. :whistle:
Link to post
Share on other sites
Guest Bilou_Gateux

@Proph,

I can't say better than your answer.

@blindwig

Having a gui is usefull when installing Unattended Windows.

From winnt.sif DetachedProgram or $OEM$\cmdlines.txt, you can launch some commands with parameters.

you probably never heard of this... each user have different needs.

@ezzetabi

i will try looking in the tutorials for more details about this command and add this to code.

Thanks.

Link to post
Share on other sites

@Bilou_Gateux

As you requested...

Here is what you need to call the progressbar from any script. :whistle:

Just call the exe with 2 parameters...

Parameter 1 is the source.

Parameter 2 is the destination.

So if you named it progressbar.exe and wanted to copy "c:\source" to "d:\destination" you would put it in your batch file or script like this...

progressbar.exe "c:\source" "d:\destination"

If $cmdline[0] = 2 Then
    $sOriginalDir = $cmdline[1]
    $sDestDir = $cmdline[2]
Else
    MsgBox(0,'Invalid # of parameters!',$cmdline[0]&' is an Invalid number of parameters.')
    Exit
EndIf

Func _CopyDirWithProgress($sOriginalDir, $sDestDir)
 ;$sOriginalDir and $sDestDir are quite selfexplanatory...
 ;This func returns:
 ; -1 in case of critical error, bad original or destination dir
 ;  0 if everything went all right
 ; >0 is the number of file not copied and it makes a log file
 ;  if in the log appear as error message '0 file copied' it is a bug of some windows' copy command that does not redirect output... 
   
   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 = _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)
  
   _Quick_Sort($aFileList, 1, $aFileList[0])
   
   $iDirSize = Int(DirGetSize($sOriginalDir) / 1024)

   ProgressSet(Int($fProgress * 100), $aFileList[$c], 'Coping file:')
   For $c = 1 To $aFileList[0]
      $FileName = StringTrimLeft($aFileList[$c], $Sl)
      ProgressSet(Int($fProgress * 100), $aFileList[$c] & ' -> '& $sDestDir & $FileName & @LF & 'Total KiB: ' & $iDirSize & @LF & 'Done KiB: ' & $iCopiedSize, 'Coping file:  ' & Round($fProgress * 100, 2) & ' %   ' & $c & '/' &$aFileList[0])
      
      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
  
   ProgressOff()
   
   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 _FileSearch($sIstr, $bSF = 1)
 ; $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 $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 _Quick_Sort(ByRef $SortArray, $First, $Last);Larry's code
   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 _Quick_Sort($SortArray, $First, $High)
   If ($Low < $Last) Then _Quick_Sort($SortArray, $Low, $Last)
   EndFunc ;==>_Quick_Sort
   
   _CopyDirWithProgress($sOriginalDir, $sDestDir)

Enjoy! :dance:

Link to post
Share on other sites

Nice job Proph, but you should always put all func in the bottom or in the begin of the script. Putting Functions in the middle as you did is ugly (even if it works exactly at the same way...). In fact your program seems incomplete at the first look.

I usually even put a EXIT just before the functions, in order to make clear that the main program is ended, if I need OnAutoItStart() I put it as first function.

The program is more tidy that way...

;Main program

Exit
Func OnAutoItStart()
 ;Blah
EndFunc

;Other funcs....
Link to post
Share on other sites
  • 1 year later...

If I use This script, I got this error:

C:\autoit\copy.au3 (185) : ==> Can not redeclare a parameter inside a user function.:

Local $sIstr, $bSF, $sCriteria, $sBuffer, $iH, $iH2, $sCS, $sCF, $sCF2, $sCP, $sFP, $sOutPut = '', $aNull[1]

Local ^ ERROR

+>AutoIT3.exe ended.rc:0

>Exit code: 0 Time: 11.474

and I´m a totally newbie in AutoIt

regards

slowhand63

Link to post
Share on other sites
  • 1 month later...
  • 2 weeks later...

hello. i need some help. pls anyone...

i want to add this function in my code my code is:

if FileExists("c:\test.txt") Then

run("notepad", "c:\windows\", @SW_MAXIMIZE)

Else

DirCopy("\\kill-bill\Server\", "c:\", 1)

EndIf

Exit

i want to copy files from server to my pc and i want to have a progress bor to check the status progress

Link to post
Share on other sites

thanks MHz but this script copy only 1 file... i want to copy all the folder with subfolders etc...

Copying the directory works for me. :whistle:

Try this

_FileCopy(@WindowsDir & "\Resources\",@HomeDrive & '\')

Func _FileCopy($fromFile,$tofile)
    Local $FOF_RESPOND_YES = 16
    Local $FOF_SIMPLEPROGRESS = 256
    $winShell = ObjCreate("shell.application")
    $winShell.namespace($tofile).CopyHere($fromFile,$FOF_RESPOND_YES)
EndFunc

It copies the folder and subfolders with a progress dialog.

post-2709-1171767116_thumb.png

:)

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
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...