Jewtus Posted May 14, 2015 Share Posted May 14, 2015 I'm about to start building a sync function that needs to do the following:1) Have an interface that allows you to select folders and sub folders that you want to back up2) Remember (even after closing) the selected folders3) Create a task in task scheduler that will perform the backup function4) The original interface needs to be able to see the old configurations and also update them. This was the approach I was going to take and I was looking to see if anyone has already built something like this that I can adapt or if anyone has a better idea on how I can do this.The GUI that will allow for folder selection I have not even looked into yet, but I'm pretty sure there is a sample script in Tree view that has check boxes. I was going to use that to record the folders that are going to be backed up and save the list to a txt file. Then I was going to use an xcopy script to back up the folders to a specified network location using the data in the previously created txt file to drive the xcopy function. Then I was going to create an xml output that could be imported to task scheduler. Anyone have suggestions on the GUI or the task scheduler? The xcopy function is pretty strait forward. Link to comment Share on other sites More sharing options...
Jewtus Posted May 18, 2015 Author Share Posted May 18, 2015 Update:I figured out how to do most of this, and here is my script as is right nowexpandcollapse popup#include <GUIConstantsEx.au3> #include <TreeViewConstants.au3> #include <WindowsConstants.au3> #Include <GuiTreeView.au3> #Include <File.au3> #Include <GuiListView.au3> $sNetbackup="H:\Backup" If FileExists($sNetbackup) = 0 Then DirCreate($sNetbackup) $sScriptDir=@UserProfileDir&"\Scripts\" If FileExists($sScriptDir) = 0 Then DirCreate($sScriptDir) $gui = GUICreate("File Browser", 756, 272, -1, -1) $iTree = GUICtrlCreateTreeView(0, 0, 361, 233, $GUI_SS_DEFAULT_TREEVIEW) $cButton = GUICtrlCreateButton("Save", 672, 240, 75, 25) $cAddSelected = GUICtrlCreateButton(">", 368, 40, 35, 25) $cRemoveSelected = GUICtrlCreateButton("<", 368, 72, 35, 25) $cRemoveAll = GUICtrlCreateButton("<<", 368, 104, 35, 25) $cPathList = GUICtrlCreateListView("", 408, 0, 345, 233,0x0003) _GUICtrlListView_AddColumn($cPathList,"Folder",340) ;Get old folders $aImportFolders=_CSVSplit(FileRead($sScriptDir&"Folders.txt"),",") For $p=0 to UBound($aImportFolders)-1 _GUICtrlListView_AddItem($cPathList,$aImportFolders[$p]) Next $hImage = _GUIImageList_Create(16, 16, 5, 2) _GUIImageList_AddIcon($hImage, @SystemDir & "\shell32.dll", 4) _GUIImageList_AddIcon($hImage, @SystemDir & "\shell32.dll", 54) _GUICtrlTreeView_SetNormalImageList($iTree, $hImage) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") $root = _GUICtrlTreeView_AddChild($iTree,"","C:",0) GUISetState(@SW_SHOW) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $cRemoveSelected _GUICtrlListView_DeleteItemsSelected($cPathList) Case $cRemoveAll _GUICtrlListView_DeleteAllItems($cPathList) Case $cAddSelected $sPath=GetSelectedPath($iTree) _GUICtrlListView_AddItem($cPathList,$sPath) Case $cButton $aFolders=_GUICtrlListView_CreateArray($cPathList) FileDelete($sScriptDir&"AutoBackup.bat") FileDelete($sScriptDir&"AutoBackup.xml") FileDelete($sScriptDir&"Folders.txt") For $z=1 to UBound($aFolders)-1 $splitter=StringSplit($aFolders[$z][0],"\") $sfoldername=$splitter[UBound($splitter)-1] FileWriteLine($sScriptDir&"AutoBackup.bat",'xcopy "'&$aFolders[$z][0]&'\*" "H:\Backup\'&$sfoldername&'" /S /I') FileWriteLine($sScriptDir&"Folders.txt",$aFolders[$z][0]) Next $sXMLPath=$sScriptDir&"AutoBackup.xml" FileWriteLine($sXMLPath,'<?xml version="1.0" encoding="UTF-16"?>'&@CRLF&'<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">'&@CRLF&' <Triggers>'&@CRLF&' <CalendarTrigger>'&@CRLF&' <StartBoundary>'&@YEAR&'-'&@MON&'-'&@MDAY&'T00:00:00</StartBoundary>'&@CRLF&' <Enabled>true</Enabled>'&@CRLF&' <ScheduleByDay>'&@CRLF&' <DaysInterval>1</DaysInterval>'&@CRLF&' </ScheduleByDay>'&@CRLF&' </CalendarTrigger>'&@CRLF&' </Triggers>'&@CRLF&' <Settings>'&@CRLF&' <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>'&@CRLF&' <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>'&@CRLF&' <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>'&@CRLF&' <AllowHardTerminate>true</AllowHardTerminate>'&@CRLF&' <StartWhenAvailable>true</StartWhenAvailable>'&@CRLF&' <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>'&@CRLF&' <IdleSettings>'&@CRLF&' <StopOnIdleEnd>true</StopOnIdleEnd>'&@CRLF&' <RestartOnIdle>false</RestartOnIdle>'&@CRLF&' </IdleSettings>'&@CRLF&' <AllowStartOnDemand>true</AllowStartOnDemand>'&@CRLF&' <Enabled>true</Enabled>'&@CRLF&' <Hidden>false</Hidden>'&@CRLF&' <RunOnlyIfIdle>false</RunOnlyIfIdle>'&@CRLF&' <WakeToRun>false</WakeToRun>'&@CRLF&' <ExecutionTimeLimit>P3D</ExecutionTimeLimit>'&@CRLF&' <Priority>7</Priority>'&@CRLF&' </Settings>'&@CRLF&' <Actions Context="Author">'&@CRLF&' <Exec>'&@CRLF&' <Command>"'&$sScriptDir&'AutoBackup.bat"</Command>'&@CRLF&' </Exec>'&@CRLF&' </Actions>'&@CRLF&'</Task>') $aBreakdownName=StringSplit($sXMLPath,"\") If UBound($aImportFolders)=0 then ; Check to see if a previous folder was created RunWait('schtasks /Create /XML "'&$sXMLPath&'" /TN "'&StringTrimRight($aBreakdownName[UBound($aBreakdownName)-1],4)&'"',@UserProfileDir,@SW_HIDE) Run("control schedtasks",@UserProfileDir,@SW_HIDE) GUIDelete($gui) Do Sleep(100) Until WinExists('Task Scheduler') MsgBox(0,"Process Complete","New task has been created. Click the 'Task Scheduler Library' to make changes to the saved task 'AutoBackup'.") Else GUIDelete($gui) MsgBox(0,"Process Complete","The saved task has been modified.") EndIf Exit EndSwitch WEnd Func GetSelectedPath($iTree) $hWndTreeView = GUICtrlGetHandle($iTree) $item=_GUICtrlTreeView_GetSelection($hWndTreeView) $txt = _GUICtrlTreeView_GetText($hWndTreeView,$item) Do $parent = _GUICtrlTreeView_GetParentHandle($hWndTreeView,$item) If $parent <> 0 Then $txt = _GUICtrlTreeView_GetText($hWndTreeView,$parent) & "\" & $txt $item = $parent EndIf Until $parent = 0 Return $txt EndFunc Func _SearchFolder($folder,$parent,$level=0) If $level >= 1 Then Return $folders = _FileListToArray($folder,"*",2) _FolderFunc($folders,$folder,$parent,$level) EndFunc Func _FolderFunc($folders,$folder,$parent,$level) For $i = 1 To UBound($folders)-1 $parentitem = _GUICtrlTreeView_AddChild($iTree,$parent,$folders[$i],0) _SearchFolder($folder & "\" & $folders[$i],$parentitem,$level+1) Next EndFunc Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR $hWndTreeView = GUICtrlGetHandle($iTree) $tNMHDR = DllStructCreate($tagNMHDR, $ilParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hWndTreeView Switch $iCode Case -451 $item = _GUICtrlTreeView_GetSelection($hWndTreeView) $root = $item If _GUICtrlTreeView_GetChildCount($hWndTreeView,$item) <= 0 Then $txt = _GUICtrlTreeView_GetText($hWndTreeView,$item) Do $parent = _GUICtrlTreeView_GetParentHandle($hWndTreeView,$item) If $parent <> 0 Then $txt = _GUICtrlTreeView_GetText($hWndTreeView,$parent) & "\" & $txt $item = $parent EndIf Until $parent = 0 _SearchFolder($txt,$root) EndIf EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ; #FUNCTION# ==================================================================================================================== ; Name ..........: _GUICtrlListView_CreateArray ; Description ...: Creates a 2-dimensional array from a listview. ; Syntax ........: _GUICtrlListView_CreateArray($hListView[, $sDelimeter = '|']) ; Parameters ....: $hListView - Control ID/Handle to the control ; $sDelimeter - [optional] One or more characters to use as delimiters (case sensitive). Default is '|'. ; Return values .: Success - The array returned is two-dimensional and is made up of the following: ; $aArray[0][0] = Number of rows ; $aArray[0][1] = Number of columns ; $aArray[0][2] = Delimited string of the column name(s) e.g. Column 1|Column 2|Column 3|Column nth ; $aArray[1][0] = 1st row, 1st column ; $aArray[1][1] = 1st row, 2nd column ; $aArray[1][2] = 1st row, 3rd column ; $aArray[n][0] = nth row, 1st column ; $aArray[n][1] = nth row, 2nd column ; $aArray[n][2] = nth row, 3rd column ; Author ........: guinness ; Remarks .......: GUICtrlListView.au3 should be included. ; Example .......: Yes ; =============================================================================================================================== Func _GUICtrlListView_CreateArray($hListView, $sDelimeter = '|') Local $iColumnCount = _GUICtrlListView_GetColumnCount($hListView), $iDim = 0, $iItemCount = _GUICtrlListView_GetItemCount($hListView) If $iColumnCount < 3 Then $iDim = 3 - $iColumnCount EndIf If $sDelimeter = Default Then $sDelimeter = '|' EndIf Local $aColumns = 0, $aReturn[$iItemCount + 1][$iColumnCount + $iDim] = [[$iItemCount, $iColumnCount, '']] For $i = 0 To $iColumnCount - 1 $aColumns = _GUICtrlListView_GetColumn($hListView, $i) $aReturn[0][2] &= $aColumns[5] & $sDelimeter Next $aReturn[0][2] = StringTrimRight($aReturn[0][2], StringLen($sDelimeter)) For $i = 0 To $iItemCount - 1 For $j = 0 To $iColumnCount - 1 $aReturn[$i + 1][$j] = _GUICtrlListView_GetItemText($hListView, $i, $j) Next Next Return SetError(Number($aReturn[0][0] = 0), 0, $aReturn) EndFunc ;==>_GUICtrlListView_CreateArray ; #FUNCTION# ==================================================================================================================== ; Name...........: _CSVSplit ; Description ...: Converts a string in CSV format to a two dimensional array (see comments) ; Syntax.........: CSVSplit ( $aArray [, $sDelim ] ) ; Parameters ....: $aArray - The array to convert ; $sDelim - Optional - Delimiter set to comma by default (see 2nd comment) ; Return values .: Success - Returns a two dimensional array or a one dimensional array (see 1st comment) ; Failure - Sets @error to: ; |@error = 1 - First parameter is not a valid string ; |@error = 2 - Second parameter is not a valid string ; |@error = 3 - Could not find suitable delimiter replacements ; Author ........: czardas ; Comments ......; Returns a one dimensional array if the input string does not contain the delimiter string ; ; Some CSV formats use semicolon as a delimiter instead of a comma ; ; Set the second parameter to @TAB To convert to TSV ; =============================================================================================================================== Func _CSVSplit($string, $sDelim = ",") ; Parses csv string input and returns a one or two dimensional array If Not IsString($string) Or $string = "" Then Return SetError(1, 0, 0) ; Invalid string If Not IsString($sDelim) Or $sDelim = "" Then Return SetError(2, 0, 0) ; Invalid string $string = StringRegExpReplace($string, "[\r\n]+\z", "") ; [Line Added] Remove training breaks Local $iOverride = 63743, $asDelim[3] ; $asDelim => replacements for comma, new line and double quote For $i = 0 To 2 $asDelim[$i] = __GetSubstitute($string, $iOverride) ; Choose a suitable substitution character If @error Then Return SetError(3, 0, 0) ; String contains too many unsuitable characters Next $iOverride = 0 Local $aArray = StringRegExp($string, '\A[^"]+|("+[^"]+)|"+\z', 3) ; Split string using double quotes delim - largest match $string = "" Local $iBound = UBound($aArray) For $i = 0 To $iBound -1 $iOverride += StringInStr($aArray[$i], '"', 0, -1) ; Increment by the number of adjacent double quotes per element If Mod ($iOverride +2, 2) = 0 Then ; Acts as an on/off switch $aArray[$i] = StringReplace($aArray[$i], $sDelim, $asDelim[0]) ; Replace comma delimeters $aArray[$i] = StringRegExpReplace($aArray[$i], "(\r\n)|[\r\n]", $asDelim[1]) ; Replace new line delimeters EndIf $aArray[$i] = StringReplace($aArray[$i], '""', $asDelim[2]) ; Replace double quote pairs $aArray[$i] = StringReplace($aArray[$i], '"', '') ; Delete enclosing double quotes - not paired $aArray[$i] = StringReplace($aArray[$i], $asDelim[2], '"') ; Reintroduce double quote pairs as single characters $string &= $aArray[$i] ; Rebuild the string, which includes two different delimiters Next $iOverride = 0 $aArray = StringSplit($string, $asDelim[1], 2) ; Split to get rows $iBound = UBound($aArray) Local $aCSV[$iBound][2], $aTemp For $i = 0 To $iBound -1 $aTemp = StringSplit($aArray[$i], $asDelim[0]) ; Split to get row items If Not @error Then If $aTemp[0] > $iOverride Then $iOverride = $aTemp[0] ReDim $aCSV[$iBound][$iOverride] ; Add columns to accomodate more items EndIf EndIf For $j = 1 To $aTemp[0] If StringLen($aTemp[$j]) Then If Not StringRegExp($aTemp[$j], '[^"]') Then ; Field only contains double quotes $aTemp[$j] = StringTrimLeft($aTemp[$j], 1) ; Delete enclosing double quote single char EndIf $aCSV[$i][$j -1] = $aTemp[$j] ; Populate each row EndIf Next Next If $iOverride > 1 Then Return $aCSV ; Multiple Columns Else For $i = 0 To $iBound -1 If StringLen($aArray[$i]) And (Not StringRegExp($aArray[$i], '[^"]')) Then ; Only contains double quotes $aArray[$i] = StringTrimLeft($aArray[$i], 1) ; Delete enclosing double quote single char EndIf Next Return $aArray ; Single column EndIf EndFunc ;==> _CSVSplit ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name...........: __GetSubstitute ; Description ...: Searches for a character to be used for substitution, ie one not contained within the input string ; Syntax.........: __GetSubstitute($string, ByRef $iCountdown) ; Parameters ....: $string - The string of characters to avoid ; $iCountdown - The first code point to begin checking ; Return values .: Success - Returns a suitable substitution character not found within the first parameter ; Failure - Sets @error to 1 => No substitution character available ; Author ........: czardas ; Comments ......; This function is connected to the function _CSVSplit and was not intended for general use ; $iCountdown is returned ByRef to avoid selecting the same character on subsequent calls to this function ; Initially $iCountown should be passed with a value = 63743 ; =============================================================================================================================== Func __GetSubstitute($string, ByRef $iCountdown) If $iCountdown < 57344 Then Return SetError(1, 0, "") ; Out of options Local $sTestChar For $i = $iCountdown To 57344 Step -1 $sTestChar = ChrW($i) $iCountdown -= 1 If Not StringInStr($string, $sTestChar) Then Return $sTestChar EndIf Next Return SetError(1, 0, "") ; Out of options EndFunc ;==> __GetSubstitute Link to comment Share on other sites More sharing options...
spudw2k Posted May 18, 2015 Share Posted May 18, 2015 Out of curiosity, what if any parameters are you utilizing/depending on in the XML definition that you cannot set at task creation?I've also been a fan of using robocopy for folder sync. Spoiler Things I've Made: Always On Top Tool ◊ AU History ◊ Deck of Cards ◊ HideIt ◊ ICU ◊ Icon Freezer ◊ Ipod Ejector ◊ Junos Configuration Explorer ◊ Link Downloader ◊ MD5 Folder Enumerator ◊ PassGen ◊ Ping Tool ◊ Quick NIC ◊ Read OCR ◊ RemoteIT ◊ SchTasksGui ◊ SpyCam ◊ System Scan Report Tool ◊ System UpTime ◊ Transparency Machine ◊ VMWare ESX BuilderMisc Code Snippets: ADODB Example ◊ CheckHover ◊ Detect SafeMode ◊ DynEnumArray ◊ GetNetStatData ◊ HashArray ◊ IsBetweenDates ◊ Local Admins ◊ Make Choice ◊ Recursive File List ◊ Remove Sizebox Style ◊ Retrieve PNPDeviceID ◊ Retreive SysListView32 Contents ◊ Set IE Homepage ◊ Tickle Expired Password ◊ Transpose ArrayProjects: Drive Space Usage GUI ◊ LEDkIT ◊ Plasma_kIt ◊ Scan Engine Builder ◊ SpeeDBurner ◊ SubnetCalcCool Stuff: AutoItObject UDF ◊ Extract Icon From Proc ◊ GuiCtrlFontRotate ◊ Hex Edit Funcs ◊ Run binary ◊ Service_UDF Link to comment Share on other sites More sharing options...
Jewtus Posted May 19, 2015 Author Share Posted May 19, 2015 I actually did it crude way. I created a task that I wanted in task scheduler and then exported the XML. Then I opened the XML with Notepad++ and did a regex replace on \r\n and replaced it with '&@CRLF&' which gave me the string to build the xml file the way I wanted. I subbed out the filename and passed it through from the previous function. Basically I built this because some of my colleagues don't know how task scheduler works nor do they understand what a bat file is (most of them don't even know the difference between their desktop and their C drive). This was a super crude way of me pushing something very simple on to their machines that they can control. (I actually had to walk over to show someone how to open the control panel when the screenshots of how to open control panel from the start menu wasn't clear enough to them)I avoided robocopy because I've had problems with admin priv on robocopy, but xcopy seems to work fine for me. I'm planning on blowing this out a little more to allow the list view to be right clicked so you can set the backup path for each folder otherwise they will default to the backup directory. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now