Jump to content

Backup script with progress and xcopy


 Share

Recommended Posts

Hi,

I've been using autoit for almost year - but I'm not good in programming I've been looking for backup solution with progress bar - found many solutions in archives but Ezzetabi solution was the best. But it's still not enough for me - I need a script ( like ezzetabi one ) where filecopy will be replaced with xcopy ( I can easly control that file was modified or not and then copy it or not ). Can anyone could help me ?

Regards

Pietka

P.S I posted this request also on scripts section - was recommended to come here :P

Link to comment
Share on other sites

Hi,

I've been using autoit for almost year - but I'm not good in programming I've been looking for backup solution with progress bar - found many solutions in archives but Ezzetabi solution was the best. But it's still not enough for me - I need a script ( like ezzetabi one ) where filecopy will be replaced with xcopy ( I can easly control that file was modified or not and then copy it or not ). Can anyone could help me ?

Regards

Pietka

P.S I posted this request also on scripts section - was recommended to come here :P

I don't think (and I am prepared to be corrected) that if you use xcopy through Run( @comspec etc) that you will be able to get a progres bar,You could probably make a dummy one but not an accurate one.

When using a script with filecopy, the script will contain in it somewhere a section which counts all the files to be copied and then as each file is copied it knocks one off the count deviding these figures then gives you a percentage to use for an accurate progress bar. If you use Xcopy you are just calling another program.

Link to comment
Share on other sites

Ok - filecopy has only two options - overight or not ( if file exist even modified will not be copied )

My aim is to: copy new files, copy modified - do not touch existing in backup and not modified in source.:

This is Ezzetabi source code which I would like to modify : ( hope You won't be angry on me Ezzetabi !! ):

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 KB: ' & $iDirSize & @LF & 'Done KB: ' & $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)

Can anyone help me that - xcopy is probably not necessary - but I need verification before copy function which files are modifie, which are new , which did not change at all ....

Thanks Pietka

Link to comment
Share on other sites

There is a command called FileGetTime that could probably be built into the script, not by me as I do not have the required scripting ability.


Time you enjoyed wasting is not wasted time ......T.S. Elliot
Suspense is worse than disappointment................Robert Burns
God help the man who won't help himself, because no-one else will...........My Grandmother

Link to comment
Share on other sites

After finding a file you will need to see if it exists in the backup and do FileGetTime() on the file to be copied and the file in backup and then decide if to overwrite it

Edit* Doh too slow BigDod beat me too it

Edited by ChrisL
Link to comment
Share on other sites

Hey - but your script doesn't show any progress :P

Exxetabi script is much more detailed - but I'm trying to add file verifiaction ( modified or not then decide to copy it ) function. But I'm too big lame to do this. Xcopy would be the easiest way - it verifies by itself that file has changed or not ... Please guru - help !!!

Link to comment
Share on other sites

Are you using AutoIt latest beta. It works on my computer, it show you a progress bar that get incriments by the folder sizes. It's not detailed as Exxetabi scripts but I don't have to wast time by using the Search function and creating a file list to copy. In this scripts used DirCopy() which copy the entire folder and the progress bar incriments by the Destination folder size.

Edited by Danny35d
AutoIt Scripts:NetPrinter - Network Printer UtilityRobocopyGUI - GUI interface for M$ robocopy command line
Link to comment
Share on other sites

No I'm using official version realese ... - ok where should I exactly place xcopy function in your script ?

2nd thing - I want to hide / add - source and destination - to avoid user confusion what should be copied.

Link to comment
Share on other sites

Ok I've changed ezzetabi script - and have expression error - I added runwait function but script says expression error - when I added some quotas it says string quota missing .... HELP PLEASE :P

Here is script:

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)

$Switches = "/E/H/R/Y"

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 KB: ' & $iDirSize & @LF & 'Done KB: ' & $iCopiedSize, 'Coping file: ' & Round($fProgress * 100, 2) & ' % ' & $c & '/' &$aFileList[0])

If StringInStr(FileGetAttrib($aFileList[$c]), 'd') Then

DirCreate($sDestDir & $FileName)

Else

RunWait(@ComSpec & " /C " & " Xcopy " & $aFileList[$c] & " " $sDestDir & $Switches )

;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);

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)

Link to comment
Share on other sites

is all of that stuff really necessary? Seems like you could just get the directory size from the destination folder, and the combined size of the files to be copied, then update a progress bar with the current size of the folder (less the original size) divided by the combined size of files being copied. Overwrites will not affect the progress bar as much as new files in the destination folder, but that could even be fixed by checking the files to be copied to see if they already exist before you start, then making necessary adjustment to the variable storing the combined size of files to be copied...

Link to comment
Share on other sites

Ok - As I mentioned I'm not good in programming - I am a lame :P Please if You could help me to reorgenize the script - for me it's to difficult ... any help will be appreciated !

Try calling up XCOPY.EXE instead of XCOPY. I find that if I ommit the extension then sometimes I get an error and the command never gets executed.

Link to comment
Share on other sites

What about that?

Func _xcopyWithDialog($sStartingDir, $sDestDir, $sSettings = '/i/c/e/d/h/r/y')
  Local $iPid, $iSDSize, $iODSize

  If FileExists($sStartingDir) And StringInStr(FileGetAttrib($sStartingDir), 'd') Then
     $iPid = Run(@comspec & ' /c xcopy "' & $sStartingDir & '" "' & $sDestDir & '" ' & $sSettings)
     $iSDSize = DirGetSize($sStartingDir)

     ProgressOn ( "XCopy", "Coping...")
     While ProcessExists($iPid)
        $iODSize = DirGetSize($sDestDir)
        ProgressSet(Round(100 * $iODSize / $iSDSize) )
        Sleep(100)
     WEnd
     ProgressOff( )
  Else
     Return -1
  EndIf
EndFunc
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...