Jump to content

Folder Sync Tool


llewxam
 Share

Recommended Posts

Read the script's comments, it's mentioned in them where to find all the includes.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

  • 3 months later...

I like your program very much ,but i wonder the meaning of mirror function , and if can add a function for online sync ?! Thanks :D

Mirror is actually the hardest part of the code, and honestly I never use it, so it will probably be disappearing from any future builds. The idea is to remove any files and folders in the destination that do not exist in the source. If you rename a file, or even just delete one, the Mirror function would remove that from the destination, since it no longer exists in the source. Kind of a housekeeping operation.

As for the online backup, that depends on where you save your online files. My web host (HostGator) has some sort of feature where you can set up a mapped drive to their server, as does Mozy and Jungle Disk. So, as long as your online storage provider gives you a drive letter you could use this with no problems. If you wanted to do something more like FTP, there are plenty of UDFs with FTP support, and you could do something like:

Generate an MD5 hash for a file

Save the file name and the MD5 to a database

Compare the MD5 from your file to the MD5 on the server

Update if the MD5 is different.

Thanks for the comments.

Ian

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.
Link to comment
Share on other sites

  • 3 months later...

Please don't remove the mirror function !

I use it a lot in my scripts, for example updating a web server where is important to delete unused files.

Among my co-workers and friends sync.exe is almost famous for it's reliability in sync dirs with a lot of files (30.000+), and the mirror option is important.

We use it mostly by calling it with options in dos batch files or in various scheduling programs.

And I have never modified the source.

But This day I'am in the middle of modify it... I have to do "selective sync" and I think the func FileListToArrayXT has the right options....

For now thanks for the great work !

Link to comment
Share on other sites

Wow, a request to keep the mirror!! :wacko:

Well, I guess I will look in to keeping it. I have a new version very far along, it actually works great but one or two features need to be implemented. I am very excited to release it, but haven't worked on it in a while. One cool addition you may like is that you can build a list of tasks which get saved as a "task list" file, which you will be able to call through a batch file. That will mean putting together a batch file will take no time at all, and will be very easy and short.

Thanks a lot for your comment, I will add this to my to-do list and hopefully will get back to it soon.

Ian

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.
Link to comment
Share on other sites

Hello,

I am very excited to see this new version... :dance:

Regards

Hello,

I am very excited to see this new version... :dance:

Regards

Thanks, it is still alpha-stage, since so many features need to be put in and even the GUI may have to change radically due to some thinking I did last night, but maybe I'll toss it up anyway as a preview.....

Ian

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.
Link to comment
Share on other sites

I have modified your script to fit my needs.

Call it a “fork” but i like your work and I have this problem:

one source filled with ten of thousands .jpg files , to sync with various destinations based on filenames.

To do every day (at least..) and with mirror criteria on various destinations.

So I added (both in GUI and from command line):

option for filter files (take only...)

option for exclude files

option for on/off recurse subDirs

option for write a small report/log

The Gui:

https://picasaweb.google.com/lh/photo/qsbHviQpd-zs7AkrhpYsPdMTjNZETYmyPJy0liipFm0?feat=directlink

The code

#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=IconeNSynC.ico
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_Run_Tidy=y
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****


;~ "NSynC" - An app designed to facilitate easy copying of large amounts of files from one location to another, quickly, skipping files that do not need to
;~ be copied, with lots of real-time status information, and with several verification methods.
;~ Coded by Ian Maxwell (llewxam @ www.autoitscript/forum)
;~ Modified by t0nZ (NSC) from november 2012.
;~ Autoit 3.3.6.1
;~ Command line usage:
;~ Sync (Source path) (Destination path) {OPTIONAL [/VerifyMethod] [/PreserveDates] [/DeleteAfterSync] [/Mirror] [/Shutdown] [/(filter)] [/esclude] [/NoRecurse] [/Log]}
;~ Command line switches:
;~ The Source and Destination paths follow standard DOS syntax rules, so if your paths include a space make sure you either put the path in quotes or
;~ use the DOS/short-name path (i.e. c:progra~1 rather than C:Program Files). When using the command line switches, the Source and Destination
;~ paths are the only required arguments.
;~ /VerifyMethod: By default an IfExist is used.
;~ /VerifyBySize If the file sizes are different the Destination file is overwritten.
;~ /VerifyByDate If the Source file's Modified timestamp is newer the Destination file is overwritten.
;~ /VerifyByMD5 If the Source and Destination file's MD5 hashes are different the Destination file is overwritten.
;~ /PreserveDates: Off by default. If used, the Source file's Created, Accessed, and Modified timestamps are applied to the Destination file.
;~ Otherwise, the current day and time are used.
;~ /DeleteAfterSync: Off by default. If used, the Source file is deleted upon sync completion.
;~ If a file copy fails, the Source file will not be deleted.
;~ /Mirror: Off by default. If used, files in the Destination that do not exist in the Source are deleted. This can be fairly time-consuming.
;~ /Shutdown: Off by default. If used, the computer is shut down when the sync is completed.
;~ /Filter optional: Search filter(s), semicolon delimited . Wildcards allowed. (default: "*") (NSC)
;~ (Example: /filter"*.exe;*.txt")
;~ /Exclude optional: Exclude filter(s), semicolon delimited. Wildcards allowed.
;~ (Example: /exclude"Unins*" will remove all files/folders that begin with "Unins") (NSC)
;~ /NoRecurse optional: turn off folder recursion (NSC)
;~ /Log Turn on log: writes a file with report in the same directory of the script

;~ Thanks to:
;~ wraithdu for _LargeFileCopy http://www.autoitscript.com/forum/topic/116880-largefilecopy-udf
;~ BaKaMu and others for _FileListToArrayXT http://www.autoitscript.com/forum/topic/96952-improvement-of-included-filelisttoarray-function/page__view__findpost__p__825298
;~ Prog@ndy for GDIpProgress http://www.autoitscript.com/forum/topic/74649-progressbar-with-gdiplus
;~ Ward for his machine code MD5 http://www.autoitscript.com/forum/topic/121985-autoit-machine-code-algorithm-collection
;~ Spiff59 for multiple suggestions and improvements to this script
;~ Melba23 for consistently good suggestions and advice!!



#include <MD5.au3>; aquire this at the link above to compile
#include <Date.au3>
#include <Array.au3>
#include <GDIpProgress.au3>; aquire this at the link above to compile
#include <StaticConstants.au3>
#include <ProgressConstants.au3>
#include <File.au3>  ;(NSC)

;~ configure all options necessary for start
Local $MarqueeProgress, $FileCount, $TotalSize, $TotalTally, $FileCopiedSoFar, $OldSpeedCalcTally, $CopyDestination, $SyncedFiles, $SkippedFiles, $ScanningPath, $Green = 0x00ff11, $Blue = 0xb2ccff
Local $Started = False, $MarqueeScroll = False, $Mirroring = False
Local $Failed[1] = [0]
Local $DeleteAfterSync = False, $Mirror = False, $PreserveDates = False, $ShutdownWhenFinished = False, $RunWithSwitches = False, $VerifyMethod = "Exist"

;~ options for _StringAddThousandsSep
Local $rKey = "HKCUControl PanelInternational"
Local $sThousands = ',', $sDecimal = '.'
If $sDecimal = -1 Then $sDecimal = RegRead($rKey, "sDecimal")
If $sThousands = -1 Then $sThousands = RegRead($rKey, "sThousand")

;~ buffer for _LargeFileCopy
$iToRead = 1024 * 1024 * 8 ; 8 MB buffer, arbitrary

;~ initialize default values for filter/exclude & LOG file (NSC)
Local $Nfilter = "*", $Nexclude = "", $Recurse = True, $WriteLog = False ;(NSC)
Global $NewTime ;(NSC)
;~ check for command line switches
If $CmdLine[0] Then
If $CmdLine[0] < 2 Then
MsgBox(16, "ERROR", "Invalid number of arguments - in order to use the command line switches, you MUST specify at least the source path and the destination path.")
Exit
EndIf
$RunWithSwitches = True
$Source = $CmdLine[1]
$Target = $CmdLine[2]
If $CmdLine[0] > 2 Then
$VerifyModeSet = False
For $c = 3 To $CmdLine[0]
$ValidCmdLine = False
Select
Case StringLower($CmdLine[$c]) == "/verifybysize"
If $VerifyModeSet == True Then
MsgBox(16, "ERROR", "You must only set one VerifyBy type at a time. Check your syntax.")
Exit
Else
$VerifyMethod = "Size"
$VerifyModeSet = True
$ValidCmdLine = True
EndIf
Case StringLower($CmdLine[$c]) == "/verifybydate"
If $VerifyModeSet == True Then
MsgBox(16, "ERROR", "You must only set one VerifyBy type at a time. Check your syntax.")
Exit
Else
$VerifyMethod = "Date"
$VerifyModeSet = True
$ValidCmdLine = True
EndIf
Case StringLower($CmdLine[$c]) == "/verifybymd5"
If $VerifyModeSet == True Then
MsgBox(16, "ERROR", "You must only set one VerifyBy type at a time. Check your syntax.")
Exit
Else
$VerifyMethod = "MD5"
$VerifyModeSet = True
$ValidCmdLine = True
EndIf
Case StringLower($CmdLine[$c]) == "/preservedates"
$PreserveDates = True
$ValidCmdLine = True
Case StringLower($CmdLine[$c]) == "/deleteaftersync"
$DeleteAfterSync = True
$ValidCmdLine = True
Case StringLower($CmdLine[$c]) == "/mirror"
$Mirror = True
$ValidCmdLine = True
Case StringLower($CmdLine[$c]) == "/shutdown"
$ShutdownWhenFinished = True
$ValidCmdLine = True
Case StringInStr(StringLower($CmdLine[$c]), "/filter") ; (NSC)
$Nfilter = StringTrimLeft(StringLower($CmdLine[$c]), 7)
$ValidCmdLine = True
Case StringInStr(StringLower($CmdLine[$c]), "/exclude") ; (NSC)
$Nexclude = StringTrimLeft(StringLower($CmdLine[$c]), 8)
$ValidCmdLine = True
Case StringLower($CmdLine[$c]) == "/norecurse"
$Recurse = False
$ValidCmdLine = True
Case StringLower($CmdLine[$c]) == "/log"
$WriteLog = True
$ValidCmdLine = True
EndSelect
If $ValidCmdLine == False Then
MsgBox(16, "ERROR", "Improper syntax: " & $CmdLine[$c])
Exit
EndIf
Next
EndIf
EndIf


;~ set up GUI
$TitleText = @ScriptName
If StringInStr($TitleText, ".") Then $TitleText = StringTrimRight($TitleText, 4)
$NewTitle = $TitleText
$GUI = GUICreate($NewTitle, 400, 360, Default, Default, -1, $WS_EX_ACCEPTFILES) ; (NSC)
GUISetBkColor($Blue, $GUI)
GUICtrlSetDefBkColor($Blue)
GUISetFont(8.5)
$SourceButton = GUICtrlCreateButton("Source", 5, 5, 50, 20)
$ShowFileCount = GUICtrlCreateLabel("", 295, 15, 100, 15, $SS_RIGHT)
$SourceInput = GUICtrlCreateInput("", 5, 30, 250, 20)
$ScanPathShow = GUICtrlCreateLabel("", 5, 60, 250, 15, $DT_END_ELLIPSIS)
$MarqueeBanner = GUICtrlCreateProgress(115, 5, 170, 20, BitOR($PBS_SMOOTH, $PBS_MARQUEE))
$ShowFileSize = GUICtrlCreateLabel("", 295, 30, 100, 15, $SS_RIGHT)
$ShowSpeed = GUICtrlCreateLabel("", 295, 45, 100, 20, $SS_RIGHT)
$DestinationInput = GUICtrlCreateInput("", 5, 60, 250, 20)
$DestinationButton = GUICtrlCreateButton("Destination", 5, 85, 70, 20)
$GoButton = GUICtrlCreateButton("GO", 185, 120, 30, 20)
$FileName = GUICtrlCreateLabel("", 5, 150, 300, 15, $DT_END_ELLIPSIS)
$FileSize = GUICtrlCreateLabel("", 320, 150, 75, 15, $SS_RIGHT)
$ShowSynced = GUICtrlCreateLabel("", 295, 80, 100, 15, $SS_RIGHT)
$ShowSkipped = GUICtrlCreateLabel("", 295, 95, 100, 15, $SS_RIGHT)
$ShowFailed = GUICtrlCreateLabel("", 295, 110, 100, 15, $SS_RIGHT)

GUICtrlCreateGroup("Sync/verify copy by: (fastest, slower, slowest)", 5, 210, 285, 45)
$VerifyByExist = GUICtrlCreateRadio("If Exist", 15, 230, 50, 20)
GUICtrlSetTip(-1, "If Destination does not exist, sync")
$VerifyBySize = GUICtrlCreateRadio("File Size", 72, 230, 60, 20)
GUICtrlSetTip(-1, "If Destination size is different, sync")
$VerifyByDate = GUICtrlCreateRadio("Date", 135, 230, 40, 20)
GUICtrlSetTip(-1, "If Destination is older, sync")
$VerifyByMD5 = GUICtrlCreateRadio("MD5 Hash", 185, 230, 95, 20)
GUICtrlSetTip(-1, "If Destination contents are different, sync")
GUICtrlCreateGroup("", -99, -99, 1, 1)

GUICtrlCreateGroup("Mirror", 300, 210, 95, 45)
$NoMirror = GUICtrlCreateRadio("No", 310, 230, 30, 20)
$YesMirror = GUICtrlCreateRadio("Yes", 350, 230, 35, 20)
GUICtrlSetTip(-1, "Remove anything in the Destination that is not in the Source. WARNING: MAY BE SLOW!!!")
GUICtrlCreateGroup("", -99, -99, 1, 1)

GUICtrlCreateGroup("Delete after sync:", 5, 260, 105, 45)
$NoDelete = GUICtrlCreateRadio("No", 15, 280, 40, 20)
$YesDelete = GUICtrlCreateRadio("Yes", 65, 280, 40, 20)
GUICtrlCreateGroup("", -99, -99, 1, 1)

GUICtrlCreateGroup("Preserve File Dates:", 127, 260, 125, 45)
$NoPreserveDates = GUICtrlCreateRadio("No", 137, 280, 40, 20)
GUICtrlSetTip(-1, "Not preserving the file date is faster, but the Create, Access, and Modify dates are changed to today")
$YesPreserveDates = GUICtrlCreateRadio("Yes", 187, 280, 40, 20)
GUICtrlSetTip(-1, "Keeps the file Create, Access, and Modify dates in tact")
GUICtrlCreateGroup("", -99, -99, 1, 1)

GUICtrlCreateGroup("Shutdown when done:", 270, 260, 125, 45)
$NoShutdownWhenDone = GUICtrlCreateRadio("No", 280, 280, 40, 20)
$YesShutdownWhenDone = GUICtrlCreateRadio("Yes", 335, 280, 40, 20)
GUICtrlCreateGroup("", -99, -99, 1, 1)

$ShowElapsedTime = GUICtrlCreateLabel("", 142, 88, 120, 15)
$Quit = GUICtrlCreateCheckbox("QUIT", 195, 120, 80, 20)

; added gui parts by (NSC)
GUICtrlCreateGroup("Filter", 5, 310, 90, 45)
$Ifilter = GUICtrlCreateInput(" ", 15, 325, 70, 21)
GUICtrlSetTip($Ifilter, 'Selective Sync based on filter(s), semicolon delimited, wildcards allowed, (Example: "*.exe;*.txt" )')
GUICtrlCreateGroup("Exclude", 100, 310, 90, 45)
$Iexclude = GUICtrlCreateInput("", 110, 325, 70, 21)
GUICtrlSetTip($Iexclude, 'Selective Sync based on exclude filter(s), semicolon delimited, wildcards allowed, (Example: "Unins*" will remove all files/folders that begin with "Unins")')
GUICtrlCreateGroup("Recursive", 198, 310, 95, 45)
$Norecurse = GUICtrlCreateRadio("No", 208, 328, 35, 20)
$Yesrecurse = GUICtrlCreateRadio("Yes", 248, 328, 35, 20)
GUICtrlSetTip($Norecurse, "Turn off recursive folder sync")
GUICtrlCreateGroup("Log", 300, 310, 95, 45)
$NoLog = GUICtrlCreateRadio("No", 310, 330, 30, 20)
$YesLog = GUICtrlCreateRadio("Yes", 350, 330, 35, 20)
GUICtrlSetTip($YesLog, "Writes a text log file of sync results in the same folder of the program")
; end of added gui parts by (NSC)

GUICtrlSetState($SourceInput, $GUI_DROPACCEPTED)
GUICtrlSetState($MarqueeBanner, $GUI_HIDE)
GUICtrlSetState($DestinationButton, $GUI_HIDE)
GUICtrlSetState($DestinationInput, $GUI_DROPACCEPTED)
GUICtrlSetState($DestinationInput, $GUI_HIDE)
GUICtrlSetState($ScanPathShow, $GUI_HIDE)
GUICtrlSetState($GoButton, $GUI_HIDE)
GUICtrlSetState($VerifyByExist, $GUI_CHECKED)
GUICtrlSetState($YesPreserveDates, $GUI_CHECKED) ; was NO (NSC)
GUICtrlSetState($NoShutdownWhenDone, $GUI_CHECKED)
GUICtrlSetState($NoDelete, $GUI_CHECKED)
GUICtrlSetState($ShowElapsedTime, $GUI_HIDE)
GUICtrlSetState($Quit, $GUI_HIDE)
GUICtrlSetState($NoMirror, $GUI_CHECKED)
GUICtrlSetState($NoLog, $GUI_CHECKED) ; (NSC)
GUICtrlSetState($Yesrecurse, $GUI_CHECKED) ; (NSC)
GUICtrlSetFont($Quit, 12, 800)
GUICtrlSetTip($SourceButton, "If the Source field is blank a " & Chr(34) & "Browse for Folder" & Chr(34) & " dialog is opened. You may type a path or use Drag and Drop instead, in which case the button will validate the path.", Default, 1, 1)
GUICtrlSetTip($DestinationButton, "If the Destination field is blank a " & Chr(34) & "Browse for Folder" & Chr(34) & " dialog is opened. You may type a path or use Drag and Drop instead, in which case the button will validate the path.", Default, 1, 1)

$LogoColor = 0xffffff
GUICtrlCreateLabel("Ian Maxwell", 5, 110, 160, 15)
GUICtrlSetColor(-1, $LogoColor)
GUICtrlCreateLabel("Modified by NSC", 5, 130, 160, 15) ;(NSC)
GUICtrlSetColor(-1, $LogoColor)
$Line = GUICtrlCreateGraphic(5, 125, 110, 2)
GUICtrlSetGraphic($Line, $GUI_GR_COLOR, $LogoColor)
GUICtrlSetGraphic($Line, $GUI_GR_MOVE, 0, 1)
GUICtrlSetGraphic($Line, $GUI_GR_LINE, 110, 1)


GUISetState(@SW_SHOW, $GUI)
;~ done with GUI


Do
$MSG = GUIGetMsg()
If $MSG = $GUI_EVENT_CLOSE Then Exit
If $RunWithSwitches == True Then
Select
Case $VerifyMethod = "Size"
GUICtrlSetState($VerifyBySize, $GUI_CHECKED)
Case $VerifyMethod = "Date"
GUICtrlSetState($VerifyByDate, $GUI_CHECKED)
Case $VerifyMethod = "MD5"
GUICtrlSetState($VerifyByMD5, $GUI_CHECKED)
EndSelect
If $DeleteAfterSync = True Then GUICtrlSetState($YesDelete, $GUI_CHECKED)
If $Mirror = True Then GUICtrlSetState($YesMirror, $GUI_CHECKED)
If $PreserveDates = True Then GUICtrlSetState($YesPreserveDates, $GUI_CHECKED)
If $ShutdownWhenFinished = True Then GUICtrlSetState($YesShutdownWhenDone, $GUI_CHECKED)
If $Recurse = False Then GUICtrlSetState($Norecurse, $GUI_CHECKED) ;(NSC)
If $WriteLog = True Then GUICtrlSetState($YesLog, $GUI_CHECKED) ;(NSC)

If Not FileExists($Source) Then
MsgBox(48, "ERROR", "There has been a problem with the source specified, please check the source location:" & @CRLF & @CRLF & $Source)
Exit
Else
If StringLen($Source) > 3 Then
$SourcePathLength = StringLen($Source) + 1
Else
$SourcePathLength = 3
EndIf
$attrib = FileGetAttrib($Source)
If StringInStr($attrib, "D") Then
$MarqueeScroll = True
AdlibRegister("_MarqueeScroll", 50)
AdlibRegister("_SpeedCalc")
GUICtrlSetState($MarqueeBanner, $GUI_SHOW)
GUICtrlSetState($ScanPathShow, $GUI_SHOW)
;$FileList = _FileListToArrayXT($Source, Default, 1, 2, True) ; original line
$FileList = _FileListToArrayXT($Source, $Nfilter, 1, 2, $Recurse, $Nexclude) ; (NSC)
$FinalSize = $TotalSize
AdlibUnRegister("_MarqueeScroll")
AdlibUnRegister("_SpeedCalc")
$MarqueeScroll = False
GUICtrlSetData($ShowFileCount, _StringAddThousandsSep($FileCount) & " Files")
GUICtrlSetState($MarqueeBanner, $GUI_HIDE)
Else
$TotalSize = FileGetSize($Source)
$FileCount = 1
$Source &= "|" & $TotalSize
$FileList = StringSplit($Source, "|")
GUICtrlSetData($ShowFileCount, "1 File")
EndIf
GUICtrlDelete($ScanPathShow)
GUICtrlSetData($SourceInput, $Source)
GUICtrlSetState($SourceInput, $GUI_DISABLE)
GUICtrlSetData($ShowFileSize, _ByteSuffix($TotalSize))
GUICtrlSetState($DestinationButton, $GUI_SHOW)
GUICtrlSetState($DestinationInput, $GUI_SHOW)
GUICtrlSetData($DestinationInput, $Target)
GUICtrlSetState($DestinationInput, $GUI_DISABLE)
GUICtrlSetState($DestinationButton, $GUI_DISABLE)

If Not FileExists($Target) Then
$create = DirCreate($Target)
If $create == 0 Then
MsgBox(48, "ERROR", "There has been a problem with the source specified, please check the source location:" & @CRLF & @CRLF & $Target)
Exit
EndIf
EndIf
EndIf

If StringRight($Target, 1) <> "" Then $Target &= ""
$MSG = $GoButton
EndIf

If $MSG = $SourceButton Then

$Nfilter = StringStripWS(GUICtrlRead($Ifilter), 8) ;(NSC)--> pearl of knownlegde : white space has to be stripped down or _filelisttoarrayXT is not working with filter !!! (perla)
If $Nfilter = "" Then $Nfilter = "*" ; reset to default (NSC)
$Nexclude = StringStripWS(GUICtrlRead($Iexclude), 8) ;(NSC)
If BitAND(GUICtrlRead($Norecurse), $GUI_CHECKED) Then $Recurse = False ;(NSC)

GUICtrlSetState($Ifilter, $GUI_DISABLE) ;(NSC)
GUICtrlSetState($Iexclude, $GUI_DISABLE) ;(NSC)
GUICtrlSetState($Norecurse, $GUI_DISABLE) ;(NSC)
GUICtrlSetState($Yesrecurse, $GUI_DISABLE) ;(NSC)

$FoundLegitSource = False
$Source = GUICtrlRead($SourceInput)
If $Source <> "" Then
If Not FileExists($Source) Then
MsgBox(48, "ERROR", "There has been a problem with the source specified, please check the source location:" & @CRLF & @CRLF & $Source)
GUICtrlSetData($SourceInput, "")
Else
$FoundLegitSource = True
EndIf
Else
$Source = FileSelectFolder("Select the source folder to be synchronized", "")
If Not FileExists($Source) Then
MsgBox(48, "ERROR", "There has been a problem with the source specified, please check the source location:" & @CRLF & @CRLF & $Source)
GUICtrlSetData($SourceInput, "")
Else
GUICtrlSetData($SourceInput, $Source)
$FoundLegitSource = True
EndIf
EndIf
If $FoundLegitSource = True Then
If StringLen($Source) > 3 Then
$SourcePathLength = StringLen($Source) + 1
Else
$SourcePathLength = 3
EndIf
$attrib = FileGetAttrib($Source)
If StringInStr($attrib, "D") Then
$MarqueeScroll = True
AdlibRegister("_MarqueeScroll", 50)
AdlibRegister("_SpeedCalc")
GUICtrlSetState($MarqueeBanner, $GUI_SHOW)
GUICtrlSetState($ScanPathShow, $GUI_SHOW)
;$FileList = _FileListToArrayXT($Source, Default, 1, 2, True) ; original line
$FileList = _FileListToArrayXT($Source, $Nfilter, 1, 2, $Recurse, $Nexclude) ; (NSC)
GUICtrlDelete($ScanPathShow)
$FinalSize = $TotalSize
AdlibUnRegister("_MarqueeScroll")
AdlibUnRegister("_SpeedCalc")
$MarqueeScroll = False
GUICtrlSetData($SourceInput, $Source)
GUICtrlSetState($SourceInput, $GUI_DISABLE)
GUICtrlSetData($ShowFileCount, _StringAddThousandsSep($FileCount) & " Files")
GUICtrlSetState($MarqueeBanner, $GUI_HIDE)
GUICtrlSetData($ShowFileSize, _ByteSuffix($TotalSize))
GUICtrlSetState($DestinationButton, $GUI_SHOW)
GUICtrlSetState($DestinationInput, $GUI_SHOW)
GUICtrlSetState($SourceButton, $GUI_DISABLE)
Else
$TotalSize = FileGetSize($Source)
$FileCount = 1
$Source &= "|" & $TotalSize
$FileList = StringSplit($Source, "|")
GUICtrlSetData($SourceInput, $Source)
GUICtrlSetData($ShowFileCount, "1 File")
GUICtrlSetData($ShowFileSize, _ByteSuffix($TotalSize))
GUICtrlSetState($DestinationButton, $GUI_SHOW)
GUICtrlSetState($DestinationInput, $GUI_SHOW)
GUICtrlSetState($SourceButton, $GUI_DISABLE)
ControlFocus($TitleText, "", $DestinationButton)
EndIf
Else ; (NSC)
GUICtrlSetState($Ifilter, $GUI_ENABLE) ;(NSC)
GUICtrlSetState($Iexclude, $GUI_ENABLE) ;(NSC)
GUICtrlSetState($Norecurse, $GUI_ENABLE) ;(NSC)
GUICtrlSetState($Yesrecurse, $GUI_ENABLE) ;(NSC)
EndIf
EndIf

If $MSG = $DestinationButton Then
$FoundLegitSource = False
$Target = GUICtrlRead($DestinationInput)
If $Target <> "" Then
If Not FileExists($Target) Then
$create = DirCreate($Target)
If $create = 0 Then
MsgBox(48, "ERROR", "There has been a problem with the source specified, please check the source location:" & @CRLF & @CRLF & $Target)
GUICtrlSetData($DestinationInput, "")
Else
$FoundLegitSource = True
EndIf
Else
$FoundLegitSource = True
EndIf
Else
$Target = FileSelectFolder("Select the destination folder", @DesktopDir, 1)
If Not FileExists($Target) Then
MsgBox(48, "ERROR", "There has been a problem with the source specified, please check the source location:" & @CRLF & @CRLF & $Target)
GUICtrlSetData($DestinationInput, "")
Else
GUICtrlSetData($DestinationInput, $Target)
GUICtrlSetState($DestinationInput, $GUI_DISABLE)
GUICtrlSetState($DestinationButton, $GUI_DISABLE)
$FoundLegitSource = True
EndIf
EndIf
If StringRight($Target, 1) <> "" Then $Target &= ""
If $FoundLegitSource = True Then GUICtrlSetState($GoButton, $GUI_SHOW)
EndIf

If $MSG = $GoButton Then

If BitAND(GUICtrlRead($VerifyBySize), $GUI_CHECKED) Then $VerifyMethod = "Size"
If BitAND(GUICtrlRead($VerifyByDate), $GUI_CHECKED) Then $VerifyMethod = "Date"
If BitAND(GUICtrlRead($VerifyByMD5), $GUI_CHECKED) Then $VerifyMethod = "MD5"
If BitAND(GUICtrlRead($YesDelete), $GUI_CHECKED) Then $DeleteAfterSync = True
If BitAND(GUICtrlRead($YesPreserveDates), $GUI_CHECKED) Then $PreserveDates = True

If BitAND(GUICtrlRead($YesLog), $GUI_CHECKED) Then $WriteLog = True ;(NSC)

GUICtrlSetState($ShowElapsedTime, $GUI_SHOW)
GUICtrlSetState($Quit, $GUI_SHOW)
GUICtrlSetState($SourceButton, $GUI_DISABLE)
GUICtrlSetState($DestinationButton, $GUI_DISABLE)
GUICtrlSetState($SourceInput, $GUI_DISABLE)
GUICtrlSetState($DestinationInput, $GUI_DISABLE)
GUICtrlSetState($VerifyByExist, $GUI_DISABLE)
GUICtrlSetState($VerifyBySize, $GUI_DISABLE)
GUICtrlSetState($VerifyByDate, $GUI_DISABLE)
GUICtrlSetState($VerifyByMD5, $GUI_DISABLE)
GUICtrlSetState($NoDelete, $GUI_DISABLE)
GUICtrlSetState($YesDelete, $GUI_DISABLE)
GUICtrlSetState($NoPreserveDates, $GUI_DISABLE)
GUICtrlSetState($YesPreserveDates, $GUI_DISABLE)
GUICtrlSetState($NoLog, $GUI_DISABLE) ;(NSC)
GUICtrlSetState($YesLog, $GUI_DISABLE) ;(NSC)
GUICtrlSetState($Norecurse, $GUI_DISABLE) ;(NSC)
GUICtrlSetState($Yesrecurse, $GUI_DISABLE) ;(NSC)

GUICtrlDelete($GoButton)
$FileProg = _ProgressCreate(5, 180, 390, 10, $Green, $Green, $Blue, $Blue)
_ProgressSetText($FileProg, "")
$TotalProg = _ProgressCreate(5, 190, 390, 10, $Green, $Green, $Blue, $Blue)
_ProgressSetText($TotalProg, "")

If StringLeft($Source, 2) == "" Then
$SourceUNCPrefix = "?UNC"
_ArrayTrim($FileList, 1, 0, 1)
$SourcePathLength -= 1
Else
$SourceUNCPrefix = "?"
EndIf

If StringLeft($Target, 2) == "" Then
$TargetUNCPrefix = "?UNC"
Else
$TargetUNCPrefix = "?"
EndIf

;~ get to work!
$Started = True
$Time = TimerInit()
$TimeLastHere = TimerInit()
AdlibRegister("_SpeedCalc")
$SourceString = ""
$DestinationString = ""

For $a = 1 To $FileList[0] Step 2
$CopySource = $FileList[$a]
$TrimPath = StringTrimLeft($CopySource, $SourcePathLength)
$Destination = $Target & $TrimPath
$NewDir = StringMid($Destination, 1, StringInStr($Destination, "", 2, -1) - 1)
If Not FileExists($NewDir) Then DirCreate($NewDir)
$CopySize = $FileList[$a + 1]
_Copy($SourceUNCPrefix & $CopySource, $TargetUNCPrefix & $Destination, $CopySize)
Next
;~ done...

;~ mirror option check
If BitAND(GUICtrlRead($YesMirror), $GUI_CHECKED) Then $Mirror = True
If $Mirror == True Then
$Mirroring = True
GUICtrlSetState($YesMirror, $GUI_DISABLE)
GUICtrlSetState($NoMirror, $GUI_DISABLE)
GUICtrlDelete($FileSize)
$CopySource = "Running Mirror now..."
If StringRight($Source, 1) <> "" Then $Source &= ""
$DestinationList = _FileListToArrayXT($Target, Default, 1, 2, $Recurse) ; this is the destination list and for "filter mirror" it don't have to be filtered ! (NSC)
$SaveCount = $DestinationList[0]

Local $NewFileList[($FileList[0] / 2) + 1]
$NewFileList[0] = ($FileList[0] / 2)
For $a = 1 To $FileList[0] Step 2
$NewFileList[$a / 2 + 1] = StringUpper($FileList[$a])
Next
_ArraySort($NewFileList)
_ArrayDelete($NewFileList, 0)

_ArrayTrim($DestinationList, StringLen($Target))
$DestinationList[0] = $SaveCount
For $a = 1 To $DestinationList[0]
$File = StringUpper($Source & $DestinationList[$a])
$Index = _ArrayBinarySearch($NewFileList, $File)
If $Index == -1 Then
FileDelete($Target & $DestinationList[$a])
EndIf
$FileCount -= 1
Next
AdlibUnRegister()
GUICtrlSetData($ShowFileCount, "0")
_EmptyDirKill($Target)
EndIf

;~ closeing GUI updates and checks
AdlibUnRegister()
$Started = False
GUICtrlSetData($ShowSynced, _StringAddThousandsSep($SyncedFiles) & " Synced")
GUICtrlSetData($ShowSkipped, _StringAddThousandsSep($SkippedFiles) & " Skipped")
GUICtrlSetData($ShowFailed, _StringAddThousandsSep(UBound($Failed) - 1) & " Failed")
GUICtrlSetState($ShowFileCount, $GUI_HIDE)
GUICtrlSetState($ShowFileSize, $GUI_HIDE)
GUICtrlSetState($ShowSpeed, $GUI_HIDE)
GUICtrlSetState($FileName, $GUI_HIDE)
GUICtrlSetState($FileSize, $GUI_HIDE)
WinSetTitle($NewTitle, "", "100% - " & $TitleText)
If $DeleteAfterSync == True Then
_EmptyDirKill($Source)
EndIf

; write a small report (NSC)
If $WriteLog = True Then
If $Failed > 0 Then
$logfilename = "NSynC_FAILED.log"
Else
$logfilename = "NSynC.log"
EndIf
_FileWriteLog(@ScriptDir & "NSynC.log", @ComputerName & "" & @UserName & "-> " & GUICtrlRead($ShowElapsedTime) & " - Synced:" & $SyncedFiles & " - Skypped:" & $SkippedFiles & "- Failed:" & $Failed)
EndIf
; end of write a small report (NSC)

If GUICtrlRead($YesMirror) == 1 Then
$Mirror = True
Else
$Mirror = False
EndIf
If BitAND(GUICtrlRead($YesShutdownWhenDone), $GUI_CHECKED) Then
$ShutdownWhenFinished = True
Else
$ShutdownWhenFinished = False
EndIf
If $ShutdownWhenFinished == True Then
Shutdown(1 + 4 + 16)
Else
If $RunWithSwitches == False Then
MsgBox(0, "Done", "The syncronization is now finished.")
If UBound($Failed) > 1 Then
_ArrayDelete($Failed, 0)
_ArrayDisplay($Failed, "Failed Items")
EndIf
Else
MsgBox(0, "Done", "The syncronization is now finished.", 3)
Exit
EndIf
EndIf
Exit
EndIf
Until 1 = 2


; (NSC) replaced with most recent version, so recursive and exclude is working
; (NSC) but I have modified the function to include external variables and to produce an array with filesizes between filenames
; #FUNCTION# ===========================================================================================
; Name: _FileListToArrayXT (modified by NSC with custom external variables ! )
; Description: Lists files andor folders in specified path(s) (Similar to using Dir with the /B Switch)
; additional features: multi-path, multi-filter, multi-exclude-filter, path format options, recursive search
; Corrected on 2010/08/19: Added FileClose()
; Syntax: _FileListToArrayXT([$sPath = @ScriptDir, [$sFilter = "*", [$iRetItemType, [$bRecursive = False, [$sExclude = "", [$iRetFormat = 1]]]]]])
; Parameter(s): $sPath = optional: Search path(s), semicolon delimited (default: @ScriptDir)
; (Example: "C:Tmp;D:Temp")
; $sFilter = optional: Search filter(s), semicolon delimited . Wildcards allowed. (default: "*")
; (Example: "*.exe;*.txt")
; $iRetItemType = Include in search: 0 = Files and Folder, 1 = Files Only, 2 = Folders Only
; $iRetPathType = Returned element format: 0 = file/folder name only, 1 = relative path, 2 = full path
; $bRecursive = optional: True: recursive search including all subdirectories
; False (default): search only in specified folder
; $sExclude = optional: Exclude filter(s), semicolon delimited. Wildcards allowed.
; (Example: "Unins*" will remove all files/folders that begin with "Unins")
; $iRetFormat = optional: return format
; 0 = one-dimensional array, 0-based
; 1 = one-dimensional array, 1-based (default)
; 2 = String ( "|" delimited)
; Requirement(s): AutoIt Version 3.3.1.1 or newer
; Return Value(s): on success: 1-based or 0-based array or string (dependent on $iRetFormat)
; If no path is found, @error and @extended are set to 1, returns empty string
; If no filter is found, @error and @extended are set to 2, returns empty string
; If $iRetFormat is invalid, @error and @extended are set to 3, returns empty string
; If no data is found, @error and @extended are set to 4, returns empty string
; Author(s): Half the AutoIt Community
; ====================================================================================================
Func _FileListToArrayXT($sPath = @ScriptDir, $sFilter = "*", $iRetItemType = 0, $iRetPathType = 0, $bRecursive = False, $sExclude = "", $iRetFormat = 1)
Local $hSearchFile, $sFile, $sFileList, $sWorkPath, $sRetPath, $iRootPathLen, $iPCount, $iFCount, $fDirFlag

;[check and prepare parameters]
;---------------
If $sPath = -1 Or $sPath = Default Then $sPath = @ScriptDir
;strip leading/trailing spaces and semi-colons, all adjacent semi-colons, and spaces surrounding semi-colons
$sPath = StringRegExpReplace(StringRegExpReplace($sPath, "(s*;s*)+", ";"), "A;|;z", "")
;check that at least one path is set
If $sPath = "" Then Return SetError(1, 1, "")
;-----
If $sFilter = -1 Or $sFilter = Default Then $sFilter = "*"
;prepare filter
;strip leading/trailing spaces and semi-colons, all adjacent semi-colons, and spaces surrounding semi-colons
$sFilter = StringRegExpReplace(StringRegExpReplace($sFilter, "(s*;s*)+", ";"), "A;|;z", "")
;check for invalid chars or that at least one filter is set
If StringRegExp($sFilter, "[/><:|]|(?s)As*z") Then Return SetError(2, 2, "")
If $bRecursive Then
;Convert $sFilter for Regular Exp[b][/b]ression
$sFilter = StringRegExpReplace($sFilter, '([Q.+[^]$(){}=!E])', '$1')
$sFilter = StringReplace($sFilter, "?", ".")
$sFilter = StringReplace($sFilter, "*", ".*?")
$sFilter = "(?i)A(" & StringReplace($sFilter, ";", "$|") & "$)" ;case-insensitive, convert ';' to '|', match from first char, terminate strings
;$sFilter = "(?i)A" & StringReplace($sFilter, ";", "|") & "z"
EndIf
;-----
If $iRetItemType <> "1" And $iRetItemType <> "2" Then $iRetItemType = "0"
;-----
If $iRetPathType <> "1" And $iRetPathType <> "2" Then $iRetPathType = "0"
;-----
$bRecursive = ($bRecursive = "1")
;-----
If $sExclude = -1 Or $sExclude = Default Then $sExclude = ""
If $sExclude Then
;prepare $sExclude
;strip leading/trailing spaces and semi-colons, all adjacent semi-colons, and spaces surrounding semi-colons
$sExclude = StringRegExpReplace(StringRegExpReplace($sExclude, "(s*;s*)+", ";"), "A;|;z", "")
;Convert $sExclude for Regular Exp[b][/b]ression
$sExclude = StringRegExpReplace($sExclude, '([Q.+[^]$(){}=!E])', '$1')
$sExclude = StringReplace($sExclude, "?", ".")
$sExclude = StringReplace($sExclude, "*", ".*?")
$sExclude = "(?i)A(" & StringReplace($sExclude, ";", "$|") & "$)" ;case-insensitive, convert ';' to '|', match from first char, terminate strings
;$sExclude = "(?i)A" & StringReplace($sExclude, ";", "|") & "z"
EndIf
;-----
;If $iRetFormat <> "0" And $iRetFormat <> "2" Then $iRetFormat = "1"
If Not ($iRetItemType = 0 Or $iRetItemType = 1 Or $iRetItemType = 2) Then Return SetError(3, 3, "")
;---------------
;[/check and prepare parameters]

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

Local $aPath = StringSplit($sPath, ';', 1) ;paths array
Local $aFilter = StringSplit($sFilter, ';', 1) ;filters array

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

If $bRecursive Then ;different handling for recursion (strategy: unfiltered search for all items and filter unwanted)

If $sExclude Then ;different handling dependent on $sExclude parameter is set or not

For $iPCount = 1 To $aPath[0] ;Path loop
$sPath = StringRegExpReplace($aPath[$iPCount], "[/]+z", "") & "" ;ensure exact one trailing slash
If Not FileExists($sPath) Then ContinueLoop
$iRootPathLen = StringLen($sPath) - 1

Local $aPathStack[1024] = [1, $sPath]

While $aPathStack[0] > 0
$sWorkPath = $aPathStack[$aPathStack[0]]
$aPathStack[0] -= 1
;-----
$hSearchFile = FileFindFirstFile($sWorkPath & '*')
If @error Then
FileClose($hSearchFile)
ContinueLoop
EndIf
;-----
Switch $iRetPathType
Case 2 ;full path
$sRetPath = $sWorkPath
Case 1 ;relative path
$sRetPath = StringTrimLeft($sWorkPath, $iRootPathLen + 1)
EndSwitch
;-----
Switch $iRetItemType
Case 1
While True ;Files only
$sFile = FileFindNextFile($hSearchFile)
If @error Then
FileClose($hSearchFile)
ExitLoop
EndIf
$fDirFlag = @extended
If $fDirFlag Then
$aPathStack[0] += 1
If UBound($aPathStack) <= $aPathStack[0] Then ReDim $aPathStack[UBound($aPathStack) * 2]
$aPathStack[$aPathStack[0]] = $sWorkPath & $sFile & ""
ContinueLoop
EndIf
If StringRegExp($sFile, $sExclude) Then ContinueLoop
If StringRegExp($sFile, $sFilter) Then
$FileCount += 1 ;(NSC)
$sFileList &= $sRetPath & $sFile & "|"
If $Mirroring == False Then
$ScanningPath = $sRetPath
$Size = FileGetSize($sRetPath & $sFile)
$TotalSize += $Size
$sFileList &= $Size & "|"
EndIf
EndIf
WEnd
Case 2
While True ;Folders only
$sFile = FileFindNextFile($hSearchFile)
If @error Then
FileClose($hSearchFile)
ExitLoop
EndIf
$fDirFlag = @extended
If StringRegExp($sFile, $sExclude) Then ContinueLoop
If $fDirFlag Then
$aPathStack[0] += 1
If UBound($aPathStack) <= $aPathStack[0] Then ReDim $aPathStack[UBound($aPathStack) * 2]
$aPathStack[$aPathStack[0]] = $sWorkPath & $sFile & ""
If StringRegExp($sFile, $sFilter) Then
$FileCount += 1
$sFileList &= $sRetPath & $sFile & "|"
If $Mirroring == False Then
$ScanningPath = $sRetPath
$Size = FileGetSize($sRetPath & $sFile)
$TotalSize += $Size
$sFileList &= $Size & "|"
EndIf
EndIf
EndIf
WEnd
Case Else
While True ;Files and Folders
$sFile = FileFindNextFile($hSearchFile)
If @error Then
FileClose($hSearchFile)
ExitLoop
EndIf
$fDirFlag = @extended
If StringRegExp($sFile, $sExclude) Then ContinueLoop
If $fDirFlag Then
$aPathStack[0] += 1
If UBound($aPathStack) <= $aPathStack[0] Then ReDim $aPathStack[UBound($aPathStack) * 2]
$aPathStack[$aPathStack[0]] = $sWorkPath & $sFile & ""
EndIf
If StringRegExp($sFile, $sFilter) Then
$FileCount += 1
$sFileList &= $sRetPath & $sFile & "|"
If $Mirroring == False Then
$ScanningPath = $sRetPath
$Size = FileGetSize($sRetPath & $sFile)
$TotalSize += $Size
$sFileList &= $Size & "|"
EndIf
EndIf
WEnd
EndSwitch
;-----
WEnd

FileClose($hSearchFile)

Next ;$iPCount - next path

Else ;If Not $sExclude

For $iPCount = 1 To $aPath[0] ;Path loop
$sPath = StringRegExpReplace($aPath[$iPCount], "[/]+z", "") & "" ;ensure exact one trailing slash
If Not FileExists($sPath) Then ContinueLoop
$iRootPathLen = StringLen($sPath) - 1

Local $aPathStack[1024] = [1, $sPath]

While $aPathStack[0] > 0
$sWorkPath = $aPathStack[$aPathStack[0]]
$aPathStack[0] -= 1
;-----
$hSearchFile = FileFindFirstFile($sWorkPath & '*')
If @error Then
FileClose($hSearchFile)
ContinueLoop
EndIf
;-----
Switch $iRetPathType
Case 2 ;full path
$sRetPath = $sWorkPath
Case 1 ;relative path
$sRetPath = StringTrimLeft($sWorkPath, $iRootPathLen + 1)
EndSwitch
;-----
Switch $iRetItemType
Case 1
While True ;Files only
$sFile = FileFindNextFile($hSearchFile)
If @error Then
FileClose($hSearchFile)
ExitLoop
EndIf
If @extended Then
$aPathStack[0] += 1
If UBound($aPathStack) <= $aPathStack[0] Then ReDim $aPathStack[UBound($aPathStack) * 2]
$aPathStack[$aPathStack[0]] = $sWorkPath & $sFile & ""
ContinueLoop
EndIf
If StringRegExp($sFile, $sFilter) Then
$FileCount += 1
$sFileList &= $sRetPath & $sFile & "|"
If $Mirroring == False Then
$ScanningPath = $sRetPath
$Size = FileGetSize($sRetPath & $sFile)
$TotalSize += $Size
$sFileList &= $Size & "|"
EndIf
EndIf
WEnd
Case 2
While True ;Folders only
$sFile = FileFindNextFile($hSearchFile)
If @error Then
FileClose($hSearchFile)
ExitLoop
EndIf
If @extended Then
$aPathStack[0] += 1
If UBound($aPathStack) <= $aPathStack[0] Then ReDim $aPathStack[UBound($aPathStack) * 2]
$aPathStack[$aPathStack[0]] = $sWorkPath & $sFile & ""
If StringRegExp($sFile, $sFilter) Then
$FileCount += 1
$sFileList &= $sRetPath & $sFile & "|"
If $Mirroring == False Then
$ScanningPath = $sRetPath
$Size = FileGetSize($sRetPath & $sFile)
$TotalSize += $Size
$sFileList &= $Size & "|"
EndIf
EndIf
EndIf
WEnd
Case Else
While True ;Files and Folders
$sFile = FileFindNextFile($hSearchFile)
If @error Then
FileClose($hSearchFile)
ExitLoop
EndIf
If @extended Then
$aPathStack[0] += 1
If UBound($aPathStack) <= $aPathStack[0] Then ReDim $aPathStack[UBound($aPathStack) * 2]
$aPathStack[$aPathStack[0]] = $sWorkPath & $sFile & ""
EndIf
If StringRegExp($sFile, $sFilter) Then
$FileCount += 1
$sFileList &= $sRetPath & $sFile & "|"
If $Mirroring == False Then
$ScanningPath = $sRetPath
$Size = FileGetSize($sRetPath & $sFile)
$TotalSize += $Size
$sFileList &= $Size & "|"
EndIf
EndIf
WEnd
EndSwitch
;-----
WEnd

FileClose($hSearchFile)

Next ;$iPCount - next path

EndIf ;If $sExclude

Else ;If Not $bRecursive (strategy: filtered search for items)

If $sExclude Then ;different handling dependent on $sExclude parameter is set or not

For $iPCount = 1 To $aPath[0] ;Path loop

$sPath = StringRegExpReplace($aPath[$iPCount], "[/]+z", "") & "" ;ensure exact one trailing slash
If Not FileExists($sPath) Then ContinueLoop
;-----
Switch $iRetPathType
Case 2 ;full path
$sRetPath = $sPath
Case 1 ;relative path
$sRetPath = ""
EndSwitch

For $iFCount = 1 To $aFilter[0] ;filter loop
;-----
$hSearchFile = FileFindFirstFile($sPath & $aFilter[$iFCount])
If @error Then
FileClose($hSearchFile)
ContinueLoop
EndIf
;-----
Switch $iRetItemType
Case 1 ;files Only
While True
$sFile = FileFindNextFile($hSearchFile)
If @error Then
FileClose($hSearchFile)
ExitLoop
EndIf
If @extended Then ContinueLoop ;bypass folder
;check for exclude files
If StringRegExp($sFile, $sExclude) Then ContinueLoop
$FileCount += 1
$sFileList &= $sRetPath & $sFile & "|"
If $Mirroring == False Then
$ScanningPath = $sRetPath
$Size = FileGetSize($sRetPath & $sFile)
$TotalSize += $Size
$sFileList &= $Size & "|"
EndIf
WEnd
Case 2 ;folders Only
While True
$sFile = FileFindNextFile($hSearchFile)
If @error Then
FileClose($hSearchFile)
ExitLoop
EndIf
If @extended Then ;bypass file
;check for exclude folder
If StringRegExp($sFile, $sExclude) Then ContinueLoop
$FileCount += 1
$sFileList &= $sRetPath & $sFile & "|"
If $Mirroring == False Then
$ScanningPath = $sRetPath
$Size = FileGetSize($sRetPath & $sFile)
$TotalSize += $Size
$sFileList &= $Size & "|"
EndIf
EndIf
WEnd
Case Else ;files and folders
While True
$sFile = FileFindNextFile($hSearchFile)
If @error Then
FileClose($hSearchFile)
ExitLoop
EndIf
;check for exclude files/folder
If StringRegExp($sFile, $sExclude) Then ContinueLoop
$FileCount += 1
$sFileList &= $sRetPath & $sFile & "|"
If $Mirroring == False Then
$ScanningPath = $sRetPath
$Size = FileGetSize($sRetPath & $sFile)
$TotalSize += $Size
$sFileList &= $Size & "|"
EndIf
WEnd
EndSwitch
FileClose($hSearchFile)
Next ;$iFCount - next filter

Next ;$iPCount - next path

Else ;If Not $sExclude

For $iPCount = 1 To $aPath[0] ;Path loop

$sPath = StringRegExpReplace($aPath[$iPCount], "[/]+z", "") & "" ;ensure exact one trailing slash
If Not FileExists($sPath) Then ContinueLoop
;-----
Switch $iRetPathType
Case 2 ;full path
$sRetPath = $sPath
Case 1 ;relative path
$sRetPath = ""
EndSwitch

For $iFCount = 1 To $aFilter[0] ;filter loop
;-----
$hSearchFile = FileFindFirstFile($sPath & $aFilter[$iFCount])
If @error Then
FileClose($hSearchFile)
ContinueLoop
EndIf
;-----
Switch $iRetItemType
Case 1 ;files Only
While True
$sFile = FileFindNextFile($hSearchFile)
If @error Then
FileClose($hSearchFile)
ExitLoop
EndIf
If @extended Then ContinueLoop ;bypass folder
$FileCount += 1
$sFileList &= $sRetPath & $sFile & "|"
If $Mirroring == False Then
$ScanningPath = $sRetPath
$Size = FileGetSize($sRetPath & $sFile)
$TotalSize += $Size
$sFileList &= $Size & "|"
EndIf
WEnd
Case 2 ;folders Only
While True
$sFile = FileFindNextFile($hSearchFile)
If @error Then
FileClose($hSearchFile)
ExitLoop
EndIf
If @extended Then ;bypass file
$FileCount += 1
$sFileList &= $sRetPath & $sFile & "|"
If $Mirroring == False Then
$ScanningPath = $sRetPath
$Size = FileGetSize($sRetPath & $sFile)
$TotalSize += $Size
$sFileList &= $Size & "|"
EndIf
EndIf
WEnd
Case Else ;files and folders
While True
$sFile = FileFindNextFile($hSearchFile)
If @error Then
FileClose($hSearchFile)
ExitLoop
EndIf
$FileCount += 1
$sFileList &= $sRetPath & $sFile & "|"
If $Mirroring == False Then
$ScanningPath = $sRetPath
$Size = FileGetSize($sRetPath & $sFile)
$TotalSize += $Size
$sFileList &= $Size & "|"
EndIf
WEnd
EndSwitch
FileClose($hSearchFile)
Next ;$iFCount - next filter

Next ;$iPCount - next path

EndIf ;If $sExclude

EndIf ;If $bRecursive

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

;set according return value
If $sFileList Then
Switch $iRetFormat
Case 2 ;return a delimited string
Return StringTrimRight($sFileList, 1)
Case 0 ;return a 0-based array
Return StringSplit(StringTrimRight($sFileList, 1), "|", 2)
Case Else ;return a 1-based array
Return StringSplit(StringTrimRight($sFileList, 1), "|", 1)
EndSwitch
Else
Return SetError(4, 4, "")
EndIf

EndFunc ;==>_FileListToArrayXT


Func _Copy($CopySource, $CopyDestination, $CopySize)
$Sync = False
$PassedVerify = False
$SourceHash = ""
If Not FileExists($CopyDestination) Then
$Sync = True
Else
Select
Case $VerifyMethod == "Size"
If FileGetSize($CopyDestination) <> $CopySize Then $Sync = True
Case $VerifyMethod == "Date"
If _CompareFileTimeEx($CopySource, $CopyDestination, 0) == 1 Then $Sync = True
Case $VerifyMethod == "MD5"
$SourceHash = _MD5(FileRead($CopySource))
If _MD5(FileRead($CopyDestination)) <> $SourceHash Then $Sync = True
EndSelect
EndIf

If $Sync == True Then; copy
$CopyTheFile = _LargeFileCopy($CopySource, $Destination, $CopySize)
If $CopyTheFile <> 1 Then
FileSetAttrib($CopySource, "-AHRS")
$CopyTheFile = _LargeFileCopy($CopySource, $Destination, $CopySize)

$WhatError = @error
EndIf
If $CopyTheFile == 1 Then; verify
If $PreserveDates == True Then _PreserveDate($CopySource, $CopyDestination)

Select
Case $VerifyMethod == "Exist"
If FileExists($CopyDestination) Then $PassedVerify = True
Case $VerifyMethod == "Size"
If FileGetSize($CopyDestination) == $CopySize Then $PassedVerify = True
Case $VerifyMethod == "Date"
If _CompareFileTimeEx($CopySource, $CopyDestination, 0) <> 1 Then $PassedVerify = True
Case $VerifyMethod == "MD5"
If $SourceHash == "" Then $SourceHash = _MD5(FileRead($CopySource))
If _MD5(FileRead($CopyDestination)) == $SourceHash Then $PassedVerify = True
EndSelect

If $PassedVerify == True Then
$SyncedFiles += 1
Else
_Error($CopySource, $CopyDestination, 6)
EndIf
Else
_Error($CopySource, $CopyDestination, $WhatError)
EndIf
Else
$SkippedFiles += 1
$TotalSize -= $CopySize
$TotalTally += $CopySize
EndIf

If $DeleteAfterSync == True Then
If $PassedVerify == True Or $Sync == False Then
FileDelete($CopySource)
EndIf
EndIf
$FileCount -= 1
EndFunc ;==>_Copy


Func _LargeFileCopy($sSrc, $sDest, $CopySize)
FileDelete($sDest) ;just to make sure that there is a fresh start on a file found to need syncing
$FileCopiedSoFar = 0

; open file for reading, fail if it doesn't exist or directory
Local $hSrc = _LFC_CreateFile($sSrc, $GENERIC_READ, $File_SHARE_READ, $OPEN_EXISTING, 0)
If Not $hSrc Then Return SetError(1, 0, 0)

; check destination
_LFC_CheckDestination($sSrc, $sDest)
If @error Then
_WinAPI_CloseHandle($hSrc)
$TotalSize -= $CopySize
Return SetError(2, 0, 0)
EndIf

; create new file for writing, overwrite
Local $hDest = _LFC_CreateFile($sDest, $GENERIC_WRITE, 0, $CREATE_ALWAYS, 0)
If Not $hDest Then
_WinAPI_CloseHandle($hSrc)
$TotalSize -= $CopySize
Return SetError(3, 0, 0)
EndIf

; check for 0 byte source file
Local $iSize = _WinAPI_GetFileSizeEx($hSrc)
If $iSize = 0 Then
; done, close handles and return success
_WinAPI_CloseHandle($hDest)
_WinAPI_CloseHandle($hSrc)
Return SetError(0, 0, 1)
EndIf

; perform copy
Local $iRead, $iWritten, $iTotal = 0, $iReadError = 0, $iWriteError = 0
Local $hBuffer = DllStructCreate("byte[" & $iToRead & "]")
Local $pBuffer = DllStructGetPtr($hBuffer)
Local $mSrc = 0

Do
If Not _WinAPI_ReadFile($hSrc, $pBuffer, $iToRead, $iRead) Then
$iReadError = 1
ExitLoop
EndIf
If $iRead = 0 Then ExitLoop ; end of file, edge case if file is an exact multiple of the buffer size
If Not _WinAPI_WriteFile($hDest, $pBuffer, $iRead, $iWritten) Or ($iRead <> $iWritten) Then
$iWriteError = 1
ExitLoop
EndIf
$FileCopiedSoFar += $iRead
$TotalTally += $iRead
$TotalSize -= $iRead
Until $iRead < $iToRead
_WinAPI_CloseHandle($hDest)
_WinAPI_CloseHandle($hSrc)

If $iReadError Then
Return SetError(4, 0, 0)
ElseIf $iWriteError Then
Return SetError(5, 0, 0)
Else
Return SetError(0, 0, 1)
EndIf
EndFunc ;==>_LargeFileCopy

#region INTERNAL FUNCTIONS
Func _LFC_CheckDestination($sSrc, ByRef $sDest)
If (StringRight($sDest, 1) = "") Or StringInStr(FileGetAttrib($sDest), "D") Then
; assume directory
If $sSrc = "" Then
; raw copy, must provide a file name
Return SetError(2)
Else
; create it
DirCreate($sDest)
; use source file name
If StringRight($sDest, 1) <> "" Then $sDest &= "" ; add trailing 
$sDest &= StringRegExpReplace($sSrc, ".*", "")
EndIf
Else
; assume file
; if destination file exists, check overwrite flag
If FileExists($sDest) Then Return SetError(1)
; create destination parent directory
DirCreate(StringRegExpReplace($sDest, "^(.*).*?$", "${1}"))
EndIf
EndFunc ;==>_LFC_CheckDestination
Func _LFC_CreateFile($sPath, $iAccess, $iShareMode, $iCreation, $iFlags)
; open the file with existing HIDDEN or SYSTEM attributes to avoid failure when using CREATE_ALWAYS
If $iCreation = $CREATE_ALWAYS Then
Local $sAttrib = FileGetAttrib($sPath)
If StringInStr($sAttrib, "H") Then $iFlags = BitOR($iFlags, $File_ATTRIBUTE_HIDDEN)
If StringInStr($sAttrib, "S") Then $iFlags = BitOR($iFlags, $File_ATTRIBUTE_SYSTEM)
EndIf
Local $hFile = DllCall("kernel32.dll", "handle", "CreateFileW", "wstr", $sPath, "dword", $iAccess, "dword", $iShareMode, "ptr", 0, _
"dword", $iCreation, "dword", $iFlags, "ptr", 0)
If @error Or ($hFile[0] = Ptr(-1)) Then Return SetError(1, 0, 0)
Return $hFile[0]
EndFunc ;==>_LFC_CreateFile
#endregion INTERNAL FUNCTIONS


Func _Error($CopySource, $CopyDestination, $WhatError)
If $WhatError == 1 Then $ErrorMessage = "**FAIL** " & Chr(34) & "Failed to open source file, or source was a directory: " & Chr(34) & $CopySource & Chr(34) & " -> " & Chr(34) & $CopyDestination & Chr(34)
If $WhatError == 2 Then $ErrorMessage = "**FAIL** " & Chr(34) & "Destination file exists and overwrite flag not set: " & Chr(34) & $CopySource & Chr(34) & " -> " & Chr(34) & $CopyDestination & Chr(34)
If $WhatError == 3 Then $ErrorMessage = "**FAIL** " & Chr(34) & "Failed to create destination file: " & Chr(34) & $CopySource & Chr(34) & " -> " & Chr(34) & $CopyDestination & Chr(34)
If $WhatError == 4 Then $ErrorMessage = "**FAIL** " & Chr(34) & "Read error during copy: " & Chr(34) & $CopySource & Chr(34) & " -> " & Chr(34) & $CopyDestination & Chr(34)
If $WhatError == 5 Then $ErrorMessage = "**FAIL** " & Chr(34) & "Write error during copy: " & Chr(34) & $CopySource & Chr(34) & " -> " & Chr(34) & $CopyDestination & Chr(34)
If $WhatError == 6 Then $ErrorMessage = "**FAIL** " & Chr(34) & "Verify failed: " & Chr(34) & $CopySource & Chr(34) & " -> " & Chr(34) & $CopyDestination & Chr(34)
If StringLen($CopySource) > 255 Then $ErrorMessage = "**FAIL** " & Chr(34) & "Source file name exceeded 255 characters: " & Chr(34) & $CopySource & Chr(34) & " -> " & Chr(34) & $CopyDestination & Chr(34)
If StringLen($CopyDestination) > 255 Then $ErrorMessage = "**FAIL** " & Chr(34) & "Source file name exceeded 255 characters: " & Chr(34) & $CopySource & Chr(34) & " -> " & Chr(34) & $CopyDestination & Chr(34)
_ArrayAdd($Failed, $ErrorMessage)
EndFunc ;==>_Error


Func _EmptyDirKill($Target)
If StringRight($Target, 1) == "" Then $Target = StringTrimRight($Target, 1)
$BaseSearch = FileFindFirstFile($Target & "*.*")
While @error <> 1
$BaseFile = FileFindNextFile($BaseSearch)
; skip these
If $BaseFile == "." Or $BaseFile == ".." Or $BaseFile == "" Then
ContinueLoop
EndIf
; if it's a non-empty dir then call this function again
$Dir = $Target & "" & $BaseFile
If StringInStr(FileGetAttrib($Dir), "D") > 0 Then
$Count = DirGetSize($Dir, 1)
If $Count[1] == 0 Then
DirRemove($Dir, 1)
Else
_EmptyDirKill($Dir)
EndIf
EndIf
WEnd
FileClose($BaseSearch)
EndFunc ;==>_EmptyDirKill


Func _CompareFileTimeEx($hSource, $hDestination, $iMethod)
;Parameters ....: $hSource - Full path to the first file
; $hDestination - Full path to the second file
; $iMethod - 0 The date and time the file was modified
; 1 The date and time the file was created
; 2 The date and time the file was accessed
;Return values .: -1 The Source file time is earlier than the Destination file time
; 0 The Source file time is equal to the Destination file time
; 1 The Source file time is later than the Destination file time
;Author ........: Ian Maxwell (llewxam @ AutoIt forum)
$aSource = FileGetTime($hSource, $iMethod, 0)
$aDestination = FileGetTime($hDestination, $iMethod, 0)
For $a = 0 To 5
If $aSource[$a] <> $aDestination[$a] Then
If $aSource[$a] < $aDestination[$a] Then
Return -1
Else
Return 1
EndIf
EndIf
Next
Return 0
EndFunc ;==>_CompareFileTimeEx


Func _PreserveDate($hSource, $hDestination)
;Author ........: Ian Maxwell (llewxam @ AutoIt forum)
$hAttrib = FileGetAttrib($hSource)
$hModifyTime = FileGetTime($hSource, 0, 1)
$hCreateTime = FileGetTime($hSource, 1, 1)
$hAccessTime = FileGetTime($hSource, 2, 1)
FileSetTime($hDestination, $hModifyTime, 0)
FileSetTime($hDestination, $hCreateTime, 1)
FileSetTime($hDestination, $hAccessTime, 2)
EndFunc ;==>_PreserveDate


Func _SpeedCalc()
If $MarqueeScroll == True Then
GUICtrlSetData($ShowFileSize, _ByteSuffix($TotalSize))
If $FileCount > 1 Then
GUICtrlSetData($ShowFileCount, _StringAddThousandsSep($FileCount) & " Files")
Else
GUICtrlSetData($ShowFileCount, _StringAddThousandsSep($FileCount) & " File")
EndIf
GUICtrlSetData($SourceInput, "Enumerating files, please wait")
GUICtrlSetData($ScanPathShow, StringTrimRight($ScanningPath, 1))
EndIf

If $Started == True Then
;~ check for quit
If BitAND(GUICtrlRead($Quit), $GUI_CHECKED) Then
AdlibUnRegister("_SpeedCalc")
$YesOrNo = MsgBox(4, "Quit?", "Quit?")
If $YesOrNo = 6 Then
FileDelete($CopyDestination)
Exit
Else
AdlibRegister("_SpeedCalc")
GUICtrlSetState($Quit, $GUI_UNCHECKED)
EndIf
EndIf

$TimeLastHereDiff = TimerDiff($TimeLastHere)
$Speed = ($TotalTally - $OldSpeedCalcTally) * $TimeLastHereDiff / 1000 * 4
$OldSpeedCalcTally = $TotalTally
If GUICtrlRead($FileName) <> $CopySource Then GUICtrlSetData($FileName, $CopySource)
$ShowCopySize = "(" & _ByteSuffix($CopySize - ($FileCopiedSoFar)) & ")"
If GUICtrlRead($FileSize) <> $ShowCopySize And $CopySize - $FileCopiedSoFar > 0 Then GUICtrlSetData($FileSize, $ShowCopySize)
_ProgressSet($FileProg, ($FileCopiedSoFar / $CopySize) * 100)

If $FileCount > 1 Then
$NewFileCountMessage = _StringAddThousandsSep($FileCount) & " Files"
If GUICtrlRead($ShowFileCount) <> $NewFileCountMessage Then GUICtrlSetData($ShowFileCount, $NewFileCountMessage)
Else
GUICtrlSetData($ShowFileCount, "1 File")
EndIf
$TotalSizeMessage = _ByteSuffix($TotalSize)
If GUICtrlRead($ShowFileSize) <> $TotalSizeMessage Then GUICtrlSetData($ShowFileSize, $TotalSizeMessage)
$SyncedFilesMessage = _StringAddThousandsSep($SyncedFiles) & " Synced"
If GUICtrlRead($ShowSynced) <> $SyncedFilesMessage Then GUICtrlSetData($ShowSynced, $SyncedFilesMessage)
$SkippedFilesMessage = _StringAddThousandsSep($SkippedFiles) & " Skipped"
If GUICtrlRead($ShowSkipped) <> $SkippedFilesMessage Then GUICtrlSetData($ShowSkipped, $SkippedFilesMessage)
$FailedFilesMessage = _StringAddThousandsSep(UBound($Failed) - 1) & " Failed"
If GUICtrlRead($ShowFailed) <> $FailedFilesMessage Then GUICtrlSetData($ShowFailed, $FailedFilesMessage)
$SpeedMessage = _ByteSuffix($Speed) & "/s"
If GUICtrlRead($ShowSpeed) <> $SpeedMessage Then GUICtrlSetData($ShowSpeed, $SpeedMessage)

$ElapsedSeconds = Int(TimerDiff($Time) / 1000)
$ElapsedMinutes = 0
$ElapsedHours = 0
Do
If $ElapsedSeconds >= 60 Then
$ElapsedSeconds -= 60
$ElapsedMinutes += 1
EndIf
Until $ElapsedSeconds < 60
Do
If $ElapsedMinutes >= 60 Then
$ElapsedMinutes -= 60
$ElapsedHours += 1
EndIf
Until $ElapsedMinutes < 60

$NewTime = "Elapsed Time: " & StringFormat('%.2i', $ElapsedHours) & ":" & StringFormat('%.2i', $ElapsedMinutes) & ":" & StringFormat('%.2i', $ElapsedSeconds)
If GUICtrlRead($ShowElapsedTime) <> $NewTime Then GUICtrlSetData($ShowElapsedTime, $NewTime)

$TimeLastHere = TimerInit()

_Title()
EndIf
EndFunc ;==>_SpeedCalc


Func _ByteSuffix($Bytes)
Local $x, $BytesSuffix[6] = [" B", " KB", " MB", " GB", " TB", " PB"]
While $Bytes > 1023
$x += 1
$Bytes /= 1024
WEnd
Return StringFormat('%.2f', $Bytes) & $BytesSuffix[$x]
EndFunc ;==>_ByteSuffix


Func _Title()
$Percent = ($FinalSize - ($FinalSize - $TotalTally)) / $FinalSize * 100
_ProgressSet($TotalProg, $Percent)
$OldTitle = $NewTitle
$NewTitle = StringFormat('%.4f', $Percent) & "%" & " - " & $TitleText
If $OldTitle <> $NewTitle Then WinSetTitle($OldTitle, "", $NewTitle)
EndFunc ;==>_Title


Func _MarqueeScroll()
$MarqueeProgress += 5
If $MarqueeProgress > 100 Then $MarqueeProgress = 0
GUICtrlSetData($MarqueeBanner, $MarqueeProgress)
EndFunc ;==>_MarqueeScroll


Func _StringAddThousandsSep($sText)
If Not StringIsInt($sText) And Not StringIsFloat($sText) Then Return 0
Local $aSplit = StringSplit($sText, "-" & $sDecimal)
Local $iInt = 1, $iMod
If Not $aSplit[1] Then
$aSplit[1] = "-"
$iInt = 2
EndIf
If $aSplit[0] > $iInt Then
$aSplit[$aSplit[0]] = "." & $aSplit[$aSplit[0]]
EndIf
$iMod = Mod(StringLen($aSplit[$iInt]), 3)
If Not $iMod Then $iMod = 3
$aSplit[$iInt] = StringRegExpReplace($aSplit[$iInt], '(?<=d{' & $iMod & '})(d{3})', $sThousands & '1')
For $i = 2 To $aSplit[0]
$aSplit[1] &= $aSplit[$i]
Next
Return $aSplit[1]
EndFunc ;==>_StringAddThousandsSep

To do this among other changes I have replaced the func _FileListToArrayXT with the most recent version i have found. (think 2010).

This code is tested only for options (and combination of) useful to me and my coworkers, modified by a poor noob (me...) so it can have serious bugs...

When I have time I want to add a simple system of store configurations , maybe a simple .ini file and a listview in the GUI...

To be very clear I respect your work and I don't want to steal attention from your original and future script , but i ask you if I can open another thread for my "fork" .

Bye, t0nZ

Edited by t0nZ
Link to comment
Share on other sites

To be very clear I respect your work and I don't want to steal attention from your original and future script , but i ask you if I can open another thread for my "fork" .

Of course, go right ahead! But, as I said before, I already have the INI "task list" feature done in the new build so don't spend too much time on that is my best suggestion. Also, I had considered (just a little though) adding exclusions to the new build, maybe that is something I should think more about as an option. The new build has 2 different recursive folder search functions for reasons you will see when I upload it, but I think they both support exclusion arguments.

So, by all means, do whatever you want with any code I upload, it is open-source for that reason. But again I suggest you wait until I upload the work as it is now, you may find everything you wanted already done, plus it is a lot faster than the previous build thanks to wraithdu's hard work!

I hope to release the current build as-is tonight for a taste test. :)

Ian

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.
Link to comment
Share on other sites

Here is the current build of Sync4. As I said, much remains to be done but it is quite usable as-is. You will see which features haven't been done yet, and they are some biggies, but again.....a sample.

Ian

Sync 4.005.zip

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.
Link to comment
Share on other sites

I have tested the new Sync and it's look promising, especially the task list, but I see the whole code and it looks very different, I wait for more mature version to benchmark against the previous "generation"...

Thank you for all your work !

Link to comment
Share on other sites

Testing this out again - will let you know if I have any issues, but came up with one right off the bat. After syncing the application closes - I used the defaults for the program, but changed the Time/Date on the Files to stay, rather then change - might want to make that default?

Anyway, thanks for sharing.

Edit - did just realize that the files keep the same time/date, but the folders do not ??? my issue not yours

$HIT - I downloaded the older version - not the 4.005 (normally the most resent is uploaded to the first post - just FYI) - I will test later

Edited by nitekram

All by me:

"Sometimes you have to go back to where you started, to get to where you want to go." 

"Everybody catches up with everyone, eventually" 

"As you teach others, you are really teaching yourself."

From my dad

"Do not worry about yesterday, as the only thing that you can control is tomorrow."

 

WindowsError.gif

WIKI | Tabs; | Arrays; | Strings | Wiki Arrays | How to ask a Question | Forum Search | FAQ | Tutorials | Original FAQ | ONLINE HELP | UDF's Wiki | AutoIt PDF

AutoIt Snippets | Multple Guis | Interrupting a running function | Another Send

StringRegExp | StringRegExp Help | RegEXTester | REG TUTOR | Reg TUTOT 2

AutoItSetOption | Macros | AutoIt Snippets | Wrapper | Autoit  Docs

SCITE | SciteJump | BB | MyTopics | Programming | UDFs | AutoIt 123 | UDFs Form | UDF

Learning to script | Tutorials | Documentation | IE.AU3 | Games? | FreeSoftware | Path_Online | Core Language

Programming Tips

Excel Changes

ControlHover.UDF

GDI_Plus

Draw_On_Screen

GDI Basics

GDI_More_Basics

GDI Rotate

GDI Graph

GDI  CheckExistingItems

GDI Trajectory

Replace $ghGDIPDll with $__g_hGDIPDll

DLL 101?

Array via Object

GDI Swimlane

GDI Plus French 101 Site

GDI Examples UEZ

GDI Basic Clock

GDI Detection

Ternary operator

Link to comment
Share on other sites

Yeah, making the timestamps preserved really should have been the default setting from the beginning! It is now on in the v4 beta builds and there isn't even an option to turn that off, so that problem will be corrected once the new version is 100%.

That is also why I did not place the beta in the first post, that is still the "official" version.

Ian

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.
Link to comment
Share on other sites

HI I think I have found a bug (in the classic version) when using this tipe of sources and destinations:

example : computernamefolder or 192.168.1.74foldersubfolder

The management of "" is the problem in this case.

The problem start in this piece of code:

If StringLeft($Source, 2) == "" Then
$SourceUNCPrefix = "?UNC"
_ArrayTrim($FileList, 1, 0, 1)
$SourcePathLength -= 1
Else
$SourceUNCPrefix = "?"
EndIf
If StringLeft($Target, 2) == "" Then
$TargetUNCPrefix = "?UNC"
Else
$TargetUNCPrefix = "?"
EndIf

So the source is like "?UNC" and the path, but the destination is like "?UNC" .

And the script crashes around this other piece of code when it fails to do filegettime from the destination, in this function

Func _CompareFileTimeEx($hSource, $hDestination, $iMethod)
;Parameters ....: $hSource - Full path to the first file
; $hDestination - Full path to the second file
; $iMethod - 0 The date and time the file was modified
; 1 The date and time the file was created
; 2 The date and time the file was accessed
;Return values .: -1 The Source file time is earlier than the Destination file time
; 0 The Source file time is equal to the Destination file time
; 1 The Source file time is later than the Destination file time
;Author ........: Ian Maxwell (llewxam @ AutoIt forum)
$aSource = FileGetTime($hSource, $iMethod, 0)
$aDestination = FileGetTime($hDestination, $iMethod, 0)
For $a = 0 To 5
If $aSource[$a] <> $aDestination[$a] Then
If $aSource[$a] < $aDestination[$a] Then
Return -1
Else
Return 1
EndIf
EndIf
Next
Return 0
EndFunc ;==>_CompareFileTimeEx

So $aDestination is empty.

From my tests It can be resolved by removing the whole "UNCprefix" thing, but I don't understand why there is need for these "UNCprefix"...

Edited by t0nZ
Link to comment
Share on other sites

Good catch, but I have no plans on any more work on the old version. I will make sure it is not repeated in the new build, though I have never had the old one crash at all....

Also, as far as I know, having the extra backslash you saw wouldn't cause an error, though it is annoying to see that happening.

The purpose of the UNC prefix is to properly support long path names. NTFS will only natively support path lengths of 255(256?) characters long, and in most cases that is fine, but there are times when I need to move something like a customer's data backup to a location where 25x is not long enough. Specifying the path as UNC will extend the allowable path length to some crazy number, 64.000+ characters if memory serves. That can cause some issues in and of itself, such as then telling Windows to delete the root folder - you will receive an error that the path is too long for Windows to delete it. I have other tricks to deal with that () but I force UNC compliance because I would rather have a folder that requires some extra work to delete VS not having all of the data get moved properly.

ahhhh, the considerations you have to make when coding! :)

I was thinking about having UNC paths be optional in the new build, but most likely will force them the same way I did in the last version.

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.
Link to comment
Share on other sites

  • 2 months later...

Sorry, no - other projects have taken my focus, and I have also been spending less time coding than usual.

Ian

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.
Link to comment
Share on other sites

  • 1 month later...

Hi llewxam

Just now I saw your folder Sync tool. By the comments and maturity it seems to be great. We are a syncBack user.

But let´s talk about real world. The reason for a backup? At least to be able to recover data when origin media crashes, ok?

Well, I have observed that most of the failures in HD´s are slow corruption, I mean, one block here, other there, and sometimes parts of directories, making files to disappear from source and so, they are deleted on destination.

Suppose this in HD´s with lots and lots of image files (100.000 to 300.000), that not so frequently are acessed. When you need a file, or, when HD finally crashes, the worst. The destination mídia (backup) does not have a lot of files..... they "disappeared" thru the time, as during sync, they didn´t exists at source....

Low level tools to check disk failures is not a solution.....

So I devised: (shortcuts -> FS= FolderSync, origin HD = oriHD, destination HD = destHD

1- FS would have an optional resident module that intercepts (as antivírus does) any call to Windows deletion routine (probably na API?).

2- this residente module would log in a "deletion log" file anything that was deleted in the oriHD(one, more or all oriHDs).

3- when FS would be doing a syncronization backup (profile= delete files at destHD not in oriHD), if it find a file that must be deleted at destHD (as it does not exists at oriHD), it will look at the "deletion log" to see if that file was deleted. If yes, it will be deleted at destHD normally. If not, it will record a warning at FS´s log and will not delete it.

4- so, my backup would be preserved, with no extra space lost!!!! Posted Image

5- more than that, looking to FS´s log, we would be able to determine on the spot what file/area is starting to corrupt, and take necessary measures.

6- if you want to go further, a HD analysis tool could be done that shows many things like corrupted disk area, list of afected directories, etc.

7- I didn´t think all the details, but probably the deleted files log shoud be flushed after a log analysis or manually by user.

8- even if this procedure creates some overhead, I think it is aceptable. Did you check how much an antivírus take of resources? A lot!!!!

How it sounds?

Jose

Link to comment
Share on other sites

Hi

Hi, after some goggle search, I found: Detecting File Changes with FileSystemWatcher

http://www.blackwasp.co.uk/FileSystemWatcher.aspx

http://www.blackwasp.co.uk/FileSystemWatcher_2.aspx

the problem is that I´m not very familiar on how to call the system functions as exposed in http://www.blackwasp.co.uk/FileSystemWatcher_2.aspx

Suppose you do a resident program that logs file creaion, deletion change and rename on monitored HDs.

Later, a "backup" program looks at this file and reproduces in backup HD what it founds at log.

It could run at night, and/or after such a a time with cpu idle, aborting if cpu become used over such a %.

If the idea sounds resonable, I think it will be much more eficiente than a standar backup, as now you know what was deleteted, no need to do comparisions!

As it fix the backup HD, it goes deleting the lines in the log (or marking them as fixed or having a incremental pointer that points to the next line in log to treat.

Any opinions?

Thanks in advance

Jose

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