Jump to content

Synchronise files in folders


Recommended Posts

I'm using 2 PC at home and I will need to sync. some of the folders in both PC.

sync. meaning that I wish to update the most recent file in the particular folder.

An example senario is that I'm using 2 PC to serve the net and I had add a few bookmarks into my favourite folder on each indivdual PC. It get me confuse after sometime to figure out at which PC I had added the link or visited that particular website.

So I wish to write a script to do the synchronise of files in some folders eg.favourites,backup,source code, etc... But unfortunately I have no idea how to start.

Anyone please give me a direction or have someone did something similar before? :)

[font="Arial"]Thanks[/font]
If @error = me Then $sorry
Else
   Do
      $clarifyMe
   Until $meClear
EndIF
MsgBox(0,"Special Message!","Special Thanks to " & $allHadReplied,$Forever)
Link to comment
Share on other sites

Write a script that checks which of the files are newer and copies the file if neccessary. Also let the script create a file index so you can see if a file was deleted and delete it on the other side.

Link to comment
Share on other sites

Hi,

There are lots of answers to this!

1. run Xcopy for DOS from an AutoIT script line.

Run Xcopy

2. Search this site ("+File + copy +newer") gives some of the previous attempts. I am not sure there is anything "already done"; Search "Xcopy" better?

**BETTER; ?XCOPy au3 script

3. There are mentions of external programs in that search.

4. Write your own as above.

5. There are vbs scripts already done if you search on google (I've seen them, not used them). You could call them; or conver them!

6. I was involved with scripts on another Macro program; see links, but would not work here.

Best, Randall

GUI by HTA , ME for Xcopy

Discussion at another Site

Edited by randallc
Link to comment
Share on other sites

Hi,

I have looked at a couple; simple to start for one directory; name your own directory and drives and re-run the "copy() function?

Seems to work on XP anyway;

Thanks

$Source_folder="C:\mdwgri\temp2\temp"

$Destination_folder="C:\mdwgri\temp2\temp2"

copy()

Exit

;--------------- Functions ---------------

Func Copy()

If StringInStr($Source_folder, " ") Then $Source_folder = '"' & $Source_folder & '"'

If StringInStr($Destination_folder, " ") Then $Destination_folder = '"' & $Destination_folder & '"'

$Command = @ComSpec & " /c " & 'xcopy '& $Source_folder &'\*.* '& $Destination_folder &' /i/c/k/h/S/E/Y/D'

RunWait($Command, @SystemDir, @SW_HIDE)

$Command = @ComSpec & " /c " & 'xcopy '& $Destination_folder &'\*.* '& $Source_folder &' /i/c/k/h/S/E/Y/D'

RunWait($Command, @SystemDir, @SW_HIDE)

EndFunc

Edited by randallc
Link to comment
Share on other sites

Hey thanks guys! :D

I'm reading through the xcopy command documentation and found that xcopy can do a error check. Is it possible to do this error check in autoIt script or I must do it in a batch file? :)

I'll prefer everything needed to be in a single script which means all code in AutoIT if possible. :D

[font="Arial"]Thanks[/font]
If @error = me Then $sorry
Else
   Do
      $clarifyMe
   Until $meClear
EndIF
MsgBox(0,"Special Message!","Special Thanks to " & $allHadReplied,$Forever)
Link to comment
Share on other sites

I'm reeally a newbie here, and not a programmer!

May be worth a "UDF"?

Here is "Help" on error from RunWait; I presume is is possible to check it all in AutIt, but do not know;

RunWait

Return Value

Success: Returns the exit code of the program that was run.

Failure: Depends on RunErrorsFatal; see Remarks.

To run DOS commands, try RunWait(@ComSpec & " /c " & "commandName")

By default the script will terminate with a fatal error if the Run function fails. To set @error to 1 as an indication of failure, see AutoItSetOption.

AutoItSetOption

"RunErrorsFatal"

Sets if the script should terminate with a fatal error if a Run/RunWait function fails due to bad paths/file not found/Bad login IDs:

1 = fatal error (default)

0 = silent error (@error set to 1)

I'll be interested to see how you go!
Link to comment
Share on other sites

@randallc

I'd tried. :) Not working to what you expected.

Success: Returns the exit code of the program that was run.

I guess it only return the exit code in state of the error code that I was expecting. :D

Exit codes for xcopy

To process exit codes returned by xcopy, use the errorlevel parameter on the if command line in a batch program. For an example of a batch program that processes exit codes using if, see Related Topics. The following table lists each exit code and a description.

Exit code - Description

0 - Files were copied without error.

1 - No files were found to copy.

2 - The user pressed CTRL+C to terminate xcopy.

4 - Initialization error occurred. There is not enough memory or disk space, or you entered an invalid drive name or invalid syntax on the command line.

5 - Disk write error occurred.

Is there anyways in autoIt to get/redirect the error code? :D

[font="Arial"]Thanks[/font]
If @error = me Then $sorry
Else
   Do
      $clarifyMe
   Until $meClear
EndIF
MsgBox(0,"Special Message!","Special Thanks to " & $allHadReplied,$Forever)
Link to comment
Share on other sites

OK-

Try this; let me know if it works;

I have made the example so the directories have same name on each drive; but you could re-do the main

Let me know if you can't put in your directory / mask pairs successfully?

;--------------- XcopyAU3 Example; Randall Clapp randallc@ozemail.com.au ---------------
Dim $DosXcopyReturn,$Display
Opt("RunErrorsFatal", 0)
$drive1="c:\"
$drive2="e:\"

;--------------- Make a list in pairs; directory without drive or trailing "\", comma, mask ---------------
$DirList = "backup\backup,*.txt|My Documents\My Pictures,*.gif"; separate pairs by "|"
$DirArray = StringSplit($DirList, "|")
$DefSwitches="/i/c/k/h/S/E/Y/D"      ; Change only if you know Xcopy switches well
for $i=1 to $DirArray[0]
$DirArrayIndiv = StringSplit($DirArray[$i], ",")
XcopyAU3($drive1&$DirArrayIndiv[1],$drive2&$DirArrayIndiv[1],$DirArrayIndiv[2],$DefSwitches)
XcopyAU3($drive2&$DirArrayIndiv[1],$drive1&$DirArrayIndiv[1],$DirArrayIndiv[2],$DefSwitches)
Next
Exit

;--------------- XcopyAU3 function; Randall Clapp randallc@ozemail.com.au  ---------------
Func XcopyAU3($directory1,$directory2, $Mask, $Switches)
If StringInStr($directory1, " ") Then $directory1 = '"' & $directory1 & '"'
If StringInStr($directory2, " ") Then $directory2 = '"' & $directory2 & '"'
$Command = @ComSpec & " /c " & 'xcopy '& $directory1 &'\'&$Mask&' '& $directory2 &' '& $Switches
$DosXcopyReturn=RunWait($Command, @SystemDir, @SW_HIDE)
ErrorHandler($DosXcopyReturn)
EndFunc
;--------------- Func ErrorHandler
Func ErrorHandler($DosXcopyReturn)
if @error then  msgbox(0,"",@error&"@error;Fatal Error")
Select
    Case $DosXcopyReturn=1
        msgbox(0,"",$DosXcopyReturn&" no files found to copy")
    Case $DosXcopyReturn=2
        msgbox(0,"",$DosXcopyReturn&" aborted by ^C")
    Case $DosXcopyReturn=3
        msgbox(0,"",$DosXcopyReturn&" Why - no such error?")
    Case $DosXcopyReturn=4
        msgbox(0,"",$DosXcopyReturn&" initialization error;(not enough memory or disk space,"&@LF&" invalid drive, or syntax error)")
    Case $DosXcopyReturn=5
        msgbox(0,"",$DosXcopyReturn&" disk write error")
EndSelect
EndFunc

Please use some trial directories and files; UNTESTED past initial couple of runs**

OK?

Edited by randallc
Link to comment
Share on other sites

Hi guys. This is what I had done so far. :D

CODE
#cs

Xcopy.exe Parameters

$spath : Required. Specifies the location and names of the files you want to copy.

This parameter must include either a drive or a path.

$dPath : Specifies the destination of the files you want to copy.

This parameter can include a drive letter and colon, a directory name, a file name, or a combination of these.

/c : Ignores errors.

/f : Displays source and destination file names while copying.

/l : Displays a list of files that are to be copied.

/d[:mm-dd-yyyy] : Copies source files changed on or after the specified date only.

If you do not include a mm-dd-yyyy value, xcopy copies all Source files that are newer than existing

Destination files. This command-line option allows you to update files that have changed.

/i : If Source is a directory or contains wildcards and Destination does not exist, xcopy assumes destination

specifies a directory name and creates a new directory. Then, xcopy copies all specified files into the new directory.

By default, xcopy prompts you to specify whether Destination is a file or a directory.

/s : Copies directories and subdirectories, unless they are empty. If you omit /s, xcopy works within a single directory.

/e : Copies all subdirectories, even if they are empty. Use /e with the /s and /t command-line options.

/k : Copies files and retains the read-only attribute on destination files if present on the source files.

By default, xcopy removes the read-only attribute.

/h : Copies files with hidden and system file attributes. By default, xcopy does not copy hidden or system files.

/y : Suppresses prompting to confirm that you want to overwrite an existing destination file.

/z : Copies over a network in restartable mode.

#ce

#include <File.au3>

#include <GUIConstants.au3>

Opt("GUIOnEventMode", 1) ; Change to OnEvent mode

Dim $source, $destination

$Source_folder = "C:\temp"

$Destination_folder = "C:\temp2"

$defaultOpts = " /c/d/i/s/e/k/h/y/z" ;Default Option to Synchronic file

$OptsToList = $defaultOpts & "/f/l" ;Additonal opteions to list files before synchronise

$mainWindow = GUICreate("listview items",400,250, 100,200)

GUISetBkColor (0x00E0FFFF) ; will change background color

GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")

$listview = GUICtrlCreateListView ("Source|To|Destination",10,10,380,150)

$syncCheckButton = GUICtrlCreateButton ("Sync Check",10,170,380,30)

$syncFilesButton = GUICtrlCreateButton ("Sync Files",10,200,380,30)

GUICtrlSetOnEvent($syncFilesButton, "syncFiles")

GUICtrlSetOnEvent($syncCheckButton, "checkSync")

GUISetState(@SW_SHOW)

While 1

Sleep(500)

WEnd

;-------------------------------

; Synchronise Files and Folders

;-------------------------------

Func _syncFnF($sPath,$dPath,$opts)

$s2dLog = @TempDir & "\syncS2D.log" ;log for copying Source->Dest.

$d2sLog = @TempDir & "\syncD2S.log" ;log for copying Dest.->Source

If StringInStr($sPath, " ") Then $sPath = '"' & $sPath & '"'

If StringInStr($dPath, " ") Then $dPath = '"' & $dPath & '"'

$Command = @ComSpec & " /c " & 'xcopy '& $sPath &'\*.* '& $dPath & $opts & " > " & $s2dLog

RunWait($Command, @SystemDir, @SW_HIDE)

$Command = @ComSpec & " /c " & 'xcopy '& $dPath &'\*.* '& $sPath & $opts & " > " & $d2sLog

RunWait($Command, @SystemDir, @SW_HIDE)

EndFunc

;---------------------------------------

; Process Synchronise Files and Folders

;---------------------------------------

Func _syncProcessInfo($logFile)

Dim $sourceList, $retVal

_FileReadToArray($logFile,$sourceList)

For $count = 1 To $sourceList[0] - 2

$sourceList[$count] = StringReplace( $sourceList[$count], " -> ", "|") ; | for column separator

$retVal = $retVal & $sourceList[$count] & "#" ; # for new line separtor

Next

Return $retVal

EndFunc

Func checkSync()

Dim $listItem, $temp

_syncFnF($Source_folder,$Destination_folder,$OptsToList)

$sourceList = _syncProcessInfo(@TempDir & "\syncS2D.log")

$destinationList = _syncProcessInfo(@TempDir & "\syncD2S.log")

$temp = "" ;clear temp

;Put files to update from source->Dest. onto list if any

$temp = StringSplit($sourceList, "#")

For $count = 1 to $temp[0] -1

$temp[$count] = StringReplace($temp[$count], "|", "|->|")

GUICtrlCreateListViewItem($temp[$count],$listview)

Next

$temp = "" ;clear temp

;Put files to update from Dest.->Source onto list if any

$temp = StringSplit($destinationList, "#")

For $count = 1 to $temp[0] -1

$temp[$count] = StringReplace($temp[$count], "|", "|<-|")

GUICtrlCreateListViewItem($temp[$count],$listview)

Next

EndFunc

Func syncFiles()

_syncFnF($Source_folder,$Destination_folder,$defaultOpts)

EndFunc

;---------------

; Exit Function

;---------------

Func CLOSEClicked()

Exit

EndFunc

I have a problem with removing the list items.

<<Question>> Can anyone give me a clue on how to remove the list items?? :huh:

Oh another issue is when I try to replace the @tempdir to @scriptdir. It always gives an error in DOS console of invalid parameters(or something like this).

Note: I'm placing my script on the desktop for trail. :(

<<Question>> Why is this so?? :D

@randallc

I'll try out your code now and see what happens. But the other time I tried, runwait function always returns a 0, no matter what senario I change it. So I doubt this will work either. But no harm trying, thanks. :)

[font="Arial"]Thanks[/font]
If @error = me Then $sorry
Else
   Do
      $clarifyMe
   Until $meClear
EndIF
MsgBox(0,"Special Message!","Special Thanks to " & $allHadReplied,$Forever)
Link to comment
Share on other sites

Hey, it looks good!

Did you try

Opt("RunErrorsFatal", 0)

and look for errors after eacg @Comspec as in my error handler; I think

@error (from Opt) (only "fatal"?) and the

$return (from Runwait) - just messages

generate 2 separate errors

Best, Randall

Link to comment
Share on other sites

@randallc

Tried. Maybe helped but I can't get the exit code 1 :D

I tried to empty a folder in either the source or dest. and delete the folder too.

The most I could get is only exit code 4... :D

Opt("RunErrorsFatal", 0)

after adding this, no difference. :huh:

What is the case on your system? Can you try to get an exit code 1 when No files were found to copy? :)

Ok now does, anyone has a fine way to remove list items? :(

[font="Arial"]Thanks[/font]
If @error = me Then $sorry
Else
   Do
      $clarifyMe
   Until $meClear
EndIF
MsgBox(0,"Special Message!","Special Thanks to " & $allHadReplied,$Forever)
Link to comment
Share on other sites

Hi,

1. @scriptDir may or may not have spaces; needs to be checked for quote needs like the other directories? -perhaps! (desktop on Win98 or XP?)

2. the new beta 14 has some new list udfs?- do they help?

3. error 1 (from xcopy, not @error) if you have a lot less switches (at least no /c, or /i , etc? (-you can see it if you have absent directories and no switches)

Good luck,

Randall

(I changed a few of your items; below)

Is your's working?

[SIZE=1]#include <File.au3>
#include <GUIConstants.au3>

Opt("GUIOnEventMode", 1); Change to OnEvent mode 
Opt("RunErrorsFatal", 0)
Dim $Source_folder, $Destination_folder,$DosXcopyReturn
$Source_folder = "C:\backup\backup"
$Destination_folder = "s:\backup\backup"
$defaultOpts = " /c/d/i/s/e/k/h/y/z";Default Option to Synchronic file
$OptsToList = $defaultOpts & "/f/l";Additonal opteions to list files before synchronise

$mainWindow = GUICreate("listview items",400,250, 100,200)
GUISetBkColor (0x00E0FFFF); will change background color
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")

$listview = GUICtrlCreateListView ("Source|To|Destination",10,10,380,150)
$syncCheckButton = GUICtrlCreateButton ("Sync Check",10,170,380,30)
$syncFilesButton = GUICtrlCreateButton ("Sync Files",10,200,380,30)
GUICtrlSetOnEvent($syncFilesButton, "syncFiles")
GUICtrlSetOnEvent($syncCheckButton, "CheckFiles")

GUISetState(@SW_SHOW)

While 1
Sleep(500)
WEnd

;-------------------------------
; Synchronise Files and Folders
;-------------------------------
Func _syncFnF($sPath,$dPath,$opts)
    MsgBox(0,"","in synch")
$s2dLog = @ScriptDir & "\syncS2D.log";log for copying Source->Dest.
$d2sLog = @ScriptDir & "\syncD2S.log";log for copying Dest.->Source
If StringInStr($sPath, " ") Then $sPath = '"' & $sPath & '"'
If StringInStr($dPath, " ") Then $dPath = '"' & $dPath & '"'
If StringInStr($s2dLog, " ") Then $s2dLog = '"' & $s2dLog & '"'
If StringInStr($d2sLog, " ") Then $d2sLog = '"' & $d2sLog & '"'
$Command = @ComSpec & " /c " & 'xcopy '& $sPath &'\*.* '& $dPath & $opts & ">" & $s2dLog
;$DosXcopyReturn=RunWait($Command, @SystemDir, @SW_HIDE)
$DosXcopyReturn=RunWait(@ComSpec & " /c " & 'xcopy '& $sPath &'\*.* '& $dPath & $opts & ">" & $s2dLog, @SystemDir, @SW_HIDE)
_ErrorHandler($DosXcopyReturn)
$Command = @ComSpec & " /c " & 'xcopy '& $dPath &'\*.* '& $sPath & $opts & ">" & $d2sLog
$DosXcopyReturn=RunWait($Command, @SystemDir, @SW_HIDE)
_ErrorHandler($DosXcopyReturn)
EndFunc
;---------------------------------------
; Process Synchronise Files and Folders
;---------------------------------------
Func _syncProcessInfo($logFile)
Dim $sourceList, $retVal
_FileReadToArray($logFile,$sourceList)
For $count = 1 To $sourceList[0] - 2
$sourceList[$count] = StringReplace( $sourceList[$count], " -> ", "|"); | for column separator
$retVal = $retVal & $sourceList[$count] & "#"; # for new line separtor
Next 
Return $retVal
EndFunc

Func checkSync()
Dim $listItem, $temp 
_syncFnF($Source_folder,$Destination_folder,$OptsToList)
$sourceList = _syncProcessInfo(@TempDir & "\syncS2D.log")
$destinationList = _syncProcessInfo(@TempDir & "\syncD2S.log")
$temp = "";clear temp
;Put files to update from source->Dest. onto list if any
$temp = StringSplit($sourceList, "#")
For $count = 1 to $temp[0] -1
$temp[$count] = StringReplace($temp[$count], "|", "|->|")
GUICtrlCreateListViewItem($temp[$count],$listview)
Next
$temp = "";clear temp
;Put files to update from Dest.->Source onto list if any
$temp = StringSplit($destinationList, "#")
For $count = 1 to $temp[0] -1
$temp[$count] = StringReplace($temp[$count], "|", "|<-|")
GUICtrlCreateListViewItem($temp[$count],$listview)
Next
EndFunc
Func CheckFiles()
_syncFnF($Source_folder,$Destination_folder,$OptsToList)
EndFunc
Func syncFiles()
_syncFnF($Source_folder,$Destination_folder,$defaultOpts)
EndFunc
Func _ErrorHandler($DosXcopyReturn)
    MsgBox(0,"","in error")
if @error then  msgbox(0,"",@error&"@error;Fatal Error")
Select
    Case $DosXcopyReturn=1
        msgbox(0,"",$DosXcopyReturn&" no dest directory to copy to")
    Case $DosXcopyReturn=2
        msgbox(0,"",$DosXcopyReturn&" aborted by ^C")
    Case $DosXcopyReturn=3
        msgbox(0,"",$DosXcopyReturn&" Why - no such error?")
    Case $DosXcopyReturn=4
        msgbox(0,"",$DosXcopyReturn&" initialization error;(not enough memory or disk space,"&@LF&" invalid drive, or syntax error)")
    Case $DosXcopyReturn=5
        msgbox(0,"",$DosXcopyReturn&" disk write error")
EndSelect
EndFunc
;---------------
; Exit Function
;---------------
Func CLOSEClicked()
$in_filename = FileOpenDialog("hi",@ScriptDir,"Logs (*.log)",5)
Exit
EndFunc[/SIZE]
Link to comment
Share on other sites

@randallc

1. @scriptDir may or may not have spaces; needs to be checked for quote needs like the other directories? -perhaps! (desktop on Win98 or XP?)

Hey thanks! Your script works with the @scriptdir thingky!

Its my mistake for neglecting these

If StringInStr($s2dLog, " ") Then $s2dLog = '"' & $s2dLog & '"'

If StringInStr($d2sLog, " ") Then $d2sLog = '"' & $d2sLog & '"'

Thanks for pointing this out.

I'm still working on an improve version of this now... Stuck with some minor problems now so came back for reading.

By the way, I got the list view remove code solved.

2. the new beta 14 has some new list udfs?- do they help?

I'm using the last stable release for this script as I want it to compile into an .exe after completion. As I tried the other time, I can get the beta versions to compile to .exe so I thought of just writing it in AutoIt v3.1.1.

3. error 1 (from xcopy, not @error) if you have a lot less switches (at least no /c, or /i , etc? (-you can see it if you have absent directories and no switches)

For this, I tried it before you mention but having the same results. Anyway, my program uses the "check sync" function to check for any files that need to be copied. So I think i may drop the idea of error check for this unless I can get it to detect the exit code 1...

$in_filename = FileOpenDialog("hi",@ScriptDir,"Logs (*.log)",5)

<<Question>> Why do you need such thing when you exit the program?

I'll post a updated version when I figure out the solutions. :)

[font="Arial"]Thanks[/font]
If @error = me Then $sorry
Else
   Do
      $clarifyMe
   Until $meClear
EndIF
MsgBox(0,"Special Message!","Special Thanks to " & $allHadReplied,$Forever)
Link to comment
Share on other sites

<<Question>> Why do you need such thing when you exit the program?

I was just looking at the logs with notepad; I was not getting anything in your list boxes at the time.

Good luck! - I will be interested to see...

(btw, I don't think DOS error 1 was ever intended to tell you if there were no files to copy; only if there was an error causing it; and it does work in that last scrip if you use non-existent directories and no switches that turn off error checking). To detect "no files to copy", you would stil need your checker, though, I think.)

(If you want @error 1 from the "runwait", I think you need to mess up the syntax badly)

EDIT Ap29th; PS - there was a problem in beta with checking "binary=1"; were you using that too?

BTW

GUICtrlSetOnEvent($addEditPreviewButton, "addEditPreview")

TestLine is added with preview button

Also, the dreaded DOS error 1 IS now working if there is no source directory, even with error checking switch on!

Randall

Edited by randallc
Link to comment
Share on other sites

@randallc

I was not getting anything in your list boxes at the time.

It should work if there is a valid path. Basically just change the $Source_folder = "C:\backup\backup" & $Destination_folder = "s:\backup\backup" to whatever path you want. Anyway, I attach a copy of what I was doing for the whole of yesterday here. :huh:

This is only a skeleton layout of what it will be when it is complete. None of the functions in the child windows are making any changes to the program(due to I had not link them up and still trying to solve problems). :">

The check sync and sync files should work fine if you change it to the required source and destination path. :(

There is one problem that I'm stuck at this stage.

I can't get the get the edit updated in my child window. :(:D

The code I'd used to update the edit is

GUICtrlSetData ($addEditPreviewPane, "Test line")
I can get it updated only if I click on the ok button and hence it spoilt my ok button functions. :(

This code should work with a single GUI window but seems to have problem when doing it in a child window. :)

Could anyone just take a look at this to see where did I go wrong? :D

FileSynchronizer.zip

[font="Arial"]Thanks[/font]
If @error = me Then $sorry
Else
   Do
      $clarifyMe
   Until $meClear
EndIF
MsgBox(0,"Special Message!","Special Thanks to " & $allHadReplied,$Forever)
Link to comment
Share on other sites

Hi,

This works for me! (3.1.1.7)

GUICtrlSetOnEvent($addEditPreviewButton, "addEditPreview")

TestLine is added with preview button

Also, the dreaded DOS error 1 IS now working if there is no source directory, even with error checking switch on!

Randall

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