Jump to content

need a little help


Haagimus
 Share

Recommended Posts

I have written a program so that i can select a source and destination folder and after a series of checks and balances to make sure all folders are legitimate it will initiate the fole copy process. It send the source folder structure to an array and everything works fine.

Problem 1) If the folder contains sub directories it will at the end of the process try to copy hundreds of files that do not exist. the array does not list these files, but when it copies it lists the invalid files as what appears to be 20 filenames concetated together therefore constituting an invalid/nonexistant file.

Problem 2) While its copying base level files everything moves along fine but when it copies a folder it hangs, for lack of a better term, the program. i understand that its hanging becuase instead of a single file its copying the directory so thats not the issue, what i would like to be able to do is set it up so that if it comes to a directory to copy that it will create a new array with the files and folders located inside THAT folder and then copy the files that way, repeating the process for each subdirectory it locates. this will not only stop hanging the program it will also let the files remaining count display correctly as well as the file currently copying name.

Problem 3) I had previously integrated a checkbox into the main GUI so that when checked it would overwrite the files during the copy process and when unchecked would not overwrite. i was able to create the checkbox and case switches successfully but ultimately ended up taking it out as the stored variable, which was 1 or 0 depending on the state, would not transfer to the variable which was in the filecopy() and dircopy(). i couldnt get this working so i deleted it, if someone knows something i dont and can get this to work i would love to keep that option switch in there.

Problem 4) The file deletion, while it works, wont delete the dest folder if it already has files in it. say i copy something into a folder thats already there and has files in it, and i cancel the copy, delete the files, select delete folder, it says it does but it does not actually remove the folder. any help appreciated on that one.

Thanks in advance for any help anyone can provide. im sure that i did some if this stuff the long way too so if anyone can see a more efficient way or better way or writing any of the code out please let me know as well. i would like this program to have as small of a system footprint as possible.

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_outfile=..\File Sync.exe
#AutoIt3Wrapper_UseX64=n
#AutoIt3Wrapper_Res_Description=Lets you backup a folder or file to a location of your choice.
#AutoIt3Wrapper_Res_Fileversion=1.0.0.3
#AutoIt3Wrapper_Res_Fileversion_AutoIncrement=p
#AutoIt3Wrapper_Res_Language=1033
#AutoIt3Wrapper_Res_Field=Developer|Gary Haag
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>
#include <GUIEdit.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>
#include <ButtonConstants.au3>
#include <File.au3>
#include <Array.au3>
#include <WindowsConstants.au3>
#include <GuiStatusBar.au3>
#include <ButtonConstants.au3>

Local $Total_Files, $Copied_Files_Array[1]

$Main = GUICreate("Backup a folder", 457, 250) ;Main GUI
GUICtrlCreateLabel("Select the folder you want to back up here:", 15, 5)
$Input_Src_Dir = GUICtrlCreateInput("", 15, 20, 300, 20) ;Inputbox
$Src_Label = GUICtrlCreateLabel("", 15, 45, 300, 18, $SS_SUNKEN) ;Inputbox label
$Set_Src = GUICtrlCreateButton("Set", 320, 19, 60, 22) ;"Set" button
$Select_Src = GUICtrlCreateButton("Browse", 385, 19, 60, 22) ;"Browse" button
$Clear_Src = GUICtrlCreateButton("Clear", 353, 45, 60, 22) ;"Clear" button
GUICtrlCreateLabel("Select where you want to copy the files here:", 15, 70)
$Input_Dest_Dir = GUICtrlCreateInput("", 15, 90, 300, 20) ;Inputbox
$Dest_Label = GUICtrlCreateLabel("", 15, 115, 300, 18, $SS_SUNKEN) ;Inputbox label
$Set_Dest = GUICtrlCreateButton("Set", 320, 89, 60, 22) ;"Set" button
$Select_Dest = GUICtrlCreateButton("Browse", 385, 89, 60, 22) ;"Browse" button
$Clear_Dest = GUICtrlCreateButton("Clear", 353, 115, 60, 22) ;"Clear" button
$Btn_1 = GUICtrlCreateButton("Start backup", 290, 195, 75) ;"Start" button
$Btn_2 = GUICtrlCreateButton("Quit", 370, 195, 75) ;"Quit" button
$Gui_Progress = GUICtrlCreateProgress(0, 227, 457, 23, $PBS_SMOOTH) ;Progress bar
GUISetState()
$Copying_label = GUICtrlCreateLabel("", 5, 140, 445, 50) ;Current file being copied label
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
$Perc_label = GUICtrlCreateLabel("", 5, 209, 90, 18) ;Progress bar, percent remaining label
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
$Remain_label = GUICtrlCreateLabel("", 100, 209, 140, 18) ;Progress bar, files remaining label
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)


While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE ;Tells the program to exit when you click the "X / Close" button
            Exit

        Case $Btn_2 ;Tells the program to exit when you click the "Quit" button
            Exit

        Case $Clear_Src ;Tells the program to clear the source folder inputbox
            _GUICtrlEdit_SetText($Src_Label, "")
            _GUICtrlEdit_SetText($Input_Src_Dir, "")

        Case $Clear_Dest ;Tells the program to clear the destination folder inputbox
            _GUICtrlEdit_SetText($Dest_Label, "")
            _GUICtrlEdit_SetText($Input_Dest_Dir, "")

        Case $Select_Src ;Opens a browse to interface
            $Src_Dir = FileSelectFolder("Select folder", "") ;Sets the source folder
            $Src_Dir_Size = DirGetSize($Src_Dir) / 1024 / 1024 ;Stores the filesize of the selected folder and converts output to MB
            $Total_Files = DirGetSize($Src_Dir, 1) ;Stores the file count of the source folder
            _GUICtrlEdit_SetText($Src_Label, "") ;Erases the source label
            If GUICtrlGetState($Src_Dir) == -1 Then ;Folder selected
                $Src_Label = GUICtrlCreateLabel(Round($Src_Dir_Size / 1024, 2) & "=GB | " & Round($Src_Dir_Size, 2) & "=MB | " _
                         & $Total_Files[2] & "=Folders | " & $Total_Files[1] & "=Files", 15, 45, 300, 20, $SS_SUNKEN) ;Populates the source label
            ElseIf GUICtrlGetState($Src_Dir) = -1 Then ;Cancel button clicked
            EndIf

            _GUICtrlEdit_SetText($Input_Src_Dir, $Src_Dir) ;Transfers the folder you select to the inputbox

        Case $Set_Src ;Tells the program to set the folder you type to the source folder
            If FileExists(GUICtrlRead($Input_Src_Dir)) Then ;Determines if the folder you typed actually exists
                $Src_Dir = GUICtrlRead($Input_Src_Dir) ;Sets the source folder
                $Src_Dir_Size = DirGetSize($Src_Dir) / 1024 / 1024 ;Stores the filesize of the selected folder and converts output to MB
                $Total_Files = DirGetSize($Src_Dir, 1) ;Stores the file count of the source folder
                _GUICtrlEdit_SetText($Src_Label, "") ;Erases the source label

                $Src_Label = GUICtrlCreateLabel(Round($Src_Dir_Size / 1024, 2) & "=GB | " & Round($Src_Dir_Size, 2) _
                         & "=MB | " & $Total_Files[2] & "=Folders | " & $Total_Files[1] & "=Files", 15, 45, 300, 20, $SS_SUNKEN) ;Populates the source label

            Else
                MsgBox(48, "Invalid", "Folder or File entered does not exist, please check spelling or use the browse button to ensure correct folder/file is selected", 15)
                _GUICtrlEdit_SetText($Src_Label, "") ;Erases the source label
                _GUICtrlEdit_SetText($Input_Src_Dir, "") ;Erases the source inputbox
            EndIf

        Case $Select_Dest ;Opens a browse to folder interface so you can select a destination folder
            $Dest_Dir = FileSelectFolder("Select folder", "", 1) ;Opens a browse to interface with "New Folder" option
            $Dest_Dir_Total = DriveSpaceFree($Dest_Dir) ;Stores the destination folder size in MB
            _GUICtrlEdit_SetText($Dest_Label, "") ;Erases the destination label
            If GUICtrlGetState($Dest_Dir) == -1 Then ;Folder selected
                $Dest_Label = GUICtrlCreateLabel(Round(DriveSpaceTotal($Dest_Dir) / 1024, 2) & " GB free", 15, 115, 300, 20, $SS_SUNKEN)
            ElseIf GUICtrlGetState($Dest_Dir) = -1 Then ;Cancel button clicked
            EndIf
            _GUICtrlEdit_SetText($Input_Dest_Dir, $Dest_Dir) ;Transfers the folder you select to the inputbox

        Case $Set_Dest ;Tells the program to set the folder you type to the destination folder
            $Dest_Dir = GUICtrlRead($Input_Dest_Dir) ;Sets the destination folder

            If DriveStatus($Dest_Dir) = "READY" Or "UNKNOWN" Then ;Checks if the drive is connected and ready
                If FileExists($Dest_Dir) Then ;Determines if the folder you typed actually exists
                    $Dest_Dir = GUICtrlRead($Input_Dest_Dir) ;Sets the destination folder
                    $Dest_Dir_Total = DriveSpaceFree($Dest_Dir) ;Stores the destination folder size in MB
                    _GUICtrlEdit_SetText($Dest_Label, "") ;Erases the destination label
                    $Dest_Label = GUICtrlCreateLabel(Round(DriveSpaceTotal($Dest_Dir) / 1024, 2) & " GB free", 15, 115, 300, 20, $SS_SUNKEN) ;Populates the destination label
                Else
                    $No_Dir = MsgBox(52, "Invalid", "Folder entered does not exist. Would you like to create it now?", 999) ;Checks if folder exists and gives the option to create it if it does not
                    If $No_Dir = 6 Then
                        DirCreate($Dest_Dir) ;Creates the directory you typed
                        $Dest_Dir = GUICtrlRead($Input_Dest_Dir) ;Sets the destination folder
                        $Dest_Dir_Total = DriveSpaceFree($Dest_Dir) ;Stores the destination folder size in MB
                        $Dest_Label = GUICtrlCreateLabel(Round(DriveSpaceTotal($Dest_Dir) / 1024, 2) & " GB free", 15, 115, 300, 20, $SS_SUNKEN) ;Populates the destination label
                    Else
                        _GUICtrlEdit_SetText($Dest_Label, "") ;Erases the destination label
                        _GUICtrlEdit_SetText($Input_Dest_Dir, "") ;Erases the destination inputbox
                    EndIf
                EndIf
            Else
                MsgBox(48, "No Drive", "The drive label you entered does not appear to be connected, check drive connections and try again.", 15)
                _GUICtrlEdit_SetText($Input_Dest_Dir, "") ;Erases the destination inputbox
            EndIf

        Case $Btn_1 ;Tells the program to proceed with the folder copy operation when the "Start" button is clicked
            If GUICtrlRead($Input_Dest_Dir) = "" Then ;Checks if a destination folder is set
                MsgBox(48, "Error", "No destination folder selected.", 15)

            ElseIf GUICtrlRead($Input_Src_Dir) = "" Then ;Checks if a source folder is set
                MsgBox(48, "Error", "No Src folder selected.", 15)

            ElseIf $Dest_Dir = $Src_Dir Then ;Checks to make sure the source and destination are not the same place
                MsgBox(48, "Error", "Destination folder cannot be the same as the Source folder", 15)
                _GUICtrlEdit_SetText($Input_Src_Dir, "") ;Erases the source label
                _GUICtrlEdit_SetText($Input_Dest_Dir, "") ;Erases the destination label

            ElseIf $Dest_Dir_Total < $Src_Dir_Size Then ;Checks stored information to make sure destination drive has more free space than the amount selected
                MsgBox(48, "Error", "Destination drive does not contain enough free space.", 15)
                _GUICtrlEdit_SetText($Input_Src_Dir, "") ;Erases the source inputbox
                _GUICtrlEdit_SetText($Src_Label, "") ;Erases the source label
                _GUICtrlEdit_SetText($Input_Dest_Dir, "") ;Erases the destination inputbox
                _GUICtrlEdit_SetText($Dest_Label, "") ;Erases the destination label
            Else

                GUICtrlSetData($Btn_1, "Stop Backup") ;Changes the "Start" button to a "Stop" button
                GUICtrlSetState($Btn_2, @SW_HIDE) ;Disables the quit button while file copy is in progress


                $File_Copy_List = _FileListToArray($Src_Dir) ;Creates and stores an array with all the files and folders in the source folder
                $Max = UBound($File_Copy_List) ;Stores the total number of files in the array

                For $Copied = 0 To $Total_Files[1] ;Starts the file copy loop (the bracketed 1 tells the program to read the total entry count in the array)

                    $m = GUIGetMsg() ;Checks to see if the "Stop" button was clicked

                    If $m = $Btn_1 Then ;"Stop" button clicked
                        MsgBox(0, "Aborted", "File copy aborted, " & $Copied & " Files still copied to " & $Dest_Dir) ;Displays how many files still copied before process was aborted
                        GUICtrlSetData($Btn_1, "Start Backup") ;Changes the "Stop" button back to a "Start" button
                        _GUICtrlEdit_SetText($Perc_label, "") ;Erases the percent remaining label
                        _GUICtrlEdit_SetText($Remain_label, "") ;Erases the files remaining label
                        _ArrayReverse($Copied_Files_Array)
                        _ArrayPop($Copied_Files_Array)
                        $Delete = MsgBox(4, "Delete files", "Do you want to delete the files that already copied?", 999)
                        If $Delete = 6 Then
                            $Delete_Total = UBound($Copied_Files_Array)
                            While $Delete_Total > 1
                                $File_to_delete = _ArrayToString($Copied_Files_Array, "", $Delete_Total, $Delete_Total - 1)
                                $Delete_Total = $Delete_Total - 1
                                FileDelete($Dest_Dir & "\" & $File_to_delete)
                            WEnd
                            MsgBox(0, "File deletion complete", "Done deleting all copied files", 15)
                            $Dest_Dir_Del = MsgBox(4, "Delete folder?", "Delete destination directory also?", 999)
                            If $Dest_Dir_Del = 6 Then
                                DirRemove($Dest_Dir)
                                MsgBox(0, "Deleted", $Dest_Dir & " Deleted", 5)
                            EndIf
                            Exit
                        Else
                            Exit ;Aborts the copy process
                        EndIf
                    Else

                        GUICtrlSetData($Gui_Progress, $Copied / $Total_Files[1] * 100) ;Calculates the percentage of files copied then sends that to the progress bar

                        $File_to_copy = _ArrayToString($File_Copy_List, "", $Max, $Max) ;Stores the last filename in the array

                        If FileGetAttrib($Src_Dir & "\" & $File_to_copy) = "D" Then ;Checks if the stored filename is a directory
                            $Dir_Files = DirGetSize($Src_Dir & "\" & $File_to_copy, 1)
                            $Copying = StringFormat("Copying folder " & $File_to_copy & " / containing " & $Dir_Files[1] & " files / folders and a total size of " & round(DirGetSize($Src_Dir & "\" & $File_to_copy) / 1024 / 1024, 2) & " MB")
                            $Perc_Done = StringFormat(Round(0 + $Copied / $Total_Files[1] * 100) & " percent done") ;Calculates and stores the percentage of files copied
                            $Remaining = StringFormat("No. of files remaining = " & $Total_Files[1] - $Copied) ;Calculates and stores the count of files remaining to be copied

                            GUICtrlSetData($Copying_label, $Copying)
                            GUICtrlSetData($Perc_label, $Perc_Done) ;Sends the percentage of files copied to the percent remaining label
                            GUICtrlSetData($Remain_label, $Remaining) ;Sends the remaining files count to the files remaining label

                            DirCopy($Src_Dir & "\" & $File_to_copy, $Dest_Dir & "\" & $File_to_copy, 0) ;Copies the directory to the destination folder
                            _ArrayAdd($Copied_Files_Array, $File_to_copy)
                            $Max = $Max - 1 ;Subtracts 1 from the total count of the array

                        Else ;Filename is not a directory
                            $Copying = StringFormat("Copying file " & $File_to_copy)
                            $Perc_Done = StringFormat(Round(0 + $Copied / $Total_Files[1] * 100) & " percent done") ;Calculates and stores the percentage of files copied
                            $Remaining = StringFormat("No. of files remaining = " & $Total_Files[1] - $Copied) ;Calculates and stores the count of files remaining to be copied

                            GUICtrlSetData($Copying_label, $Copying)
                            GUICtrlSetData($Perc_label, $Perc_Done) ;Sends the percentage of files copied to the percent remaining label
                            GUICtrlSetData($Remain_label, $Remaining) ;Sends the remaining files count to the files remaining label

                            FileCopy($Src_Dir & "\" & $File_to_copy, $Dest_Dir & "\" & $File_to_copy, 0) ;Copies the file to the destination directory
                            _ArrayAdd($Copied_Files_Array, $File_to_copy)
                            $Max = $Max - 1 ;Subtracts 1 from the total count of the array
                        EndIf

                    EndIf
                Next ;Tells the program what to do once all files are copied
                MsgBox(0, "Complete", "Backup operation complete. " & $Copied & " files copied to " & $Dest_Dir)

                $Open = MsgBox(4, "Open folder", "Would you like to open the destination folder now?", 999)
                If $Open = 6 Then
                    ShellExecute($Dest_Dir)
                Else
                    Exit
                EndIf

                GUICtrlSetData($Gui_Progress, 0) ;Clears the progress bar
            EndIf

            _GUICtrlEdit_SetText($Input_Src_Dir, "") ;Erases the source inputbox
            _GUICtrlEdit_SetText($Src_Label, "") ;Erases the source label
            _GUICtrlEdit_SetText($Input_Dest_Dir, "") ;Erases the destination inputbox
            _GUICtrlEdit_SetText($Dest_Label, "") ;Erases the destination label
            GUICtrlSetData($Perc_label, "") ;Erases the percent remaining label
            GUICtrlSetData($Remain_label, "") ;Erases the files remaining label
    EndSwitch
WEnd
Exit

sync.au3

Edited by Haagimus
Link to comment
Share on other sites

You have set quite a big and complex task for you. I won't debug your script but I will give some suggestions to make your job easier:

- To set whatever is displayed in a label/input ... you should use GUICtrlSetData - Not _GUICtrlEdit_SetText

- Calculating how many files to copy, folders and their size is over-complicating the script. You don't need that. I know, it looks fancy but, are you ready to work so hard to achieve that? Because as you said, a folder can have subfolders, and those to have subfolders at their turn ... and so on. Are you willing to parse all those folders/subfolders/subfolders ... just to tell how many files and folders to copy? I guess not - I wouldn't. Why not copying the whole source folder with everything in it - a simple DirCopy is enough for that.

- put back the checkbox where it was, create a variable named "$CopyFlag" and use the checkbox state to set tha value of this variable (if checked make the variable = 1, not checked = 0) and use the variable as the flag for "DirCopy"

- deleting copied files if backup is aborted: that could be quite sensitive, if you had "overwrite" checked and copied files just replaced the old ones - what can you do about that? delete the files?

To accomplish that, you will need to use a temporary folder to copy the files in. You will show the copy progress to this temporary folder, once it finishes, if the used didn't cancel, just move the files to destination. Move and Copy are different, moving files on the same drive is almost instant.

- have a look at these "Dir..." commands, it's what you need.

Good luck,

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Link to comment
Share on other sites

"To set whatever is displayed in a label/input ... you should use GUICtrlSetData - Not _GUICtrlEdit_SetText"

- for whatever reason, probably just me doing it wrong, i started out that way but it wouldnt clear the data and make it "dissappear" thats why i ended up using edit, will give it another shot though.

"Calculating how many files to copy, folders and their size is over-complicating the script. You don't need that. I know, it looks fancy but, are you ready to work so hard to achieve that? Because as you said, a folder can have subfolders, and those to have subfolders at their turn ... and so on. Are you willing to parse all those folders/subfolders/subfolders ... just to tell how many files and folders to copy? I guess not - I wouldn't. Why not copying the whole source folder with everything in it - a simple DirCopy is enough for that."

- i agree that it is complicated but i suppose i did all that cause im trying to learn as many features of this language as possible while i mess around making stuff like this. but you are correct it serves no purpose other than eye candy really. if i do only a single dir copy for the entire directory is there still a way to do a progress bar, from what i have seen if i do a single dir copy it will basically make the program apprear to freeze until the copy is complete?

"put back the checkbox where it was, create a variable named "$CopyFlag" and use the checkbox state to set tha value of this variable (if checked make the variable = 1, not checked = 0) and use the variable as the flag for "DirCopy"

- Copy

"deleting copied files if backup is aborted: that could be quite sensitive, if you had "overwrite" checked and copied files just replaced the old ones - what can you do about that? delete the files?"

To accomplish that, you will need to use a temporary folder to copy the files in. You will show the copy progress to this temporary folder, once it finishes, if the used didn't cancel, just move the files to destination. Move and Copy are different, moving files on the same drive is almost instant."

- just off the top of my head cant think of the commands but something like

DirCopy($source, $temp)

if dircopy aborted then

dirremove($temp)

else

Dirmove($temp, $Dest)

endif

something like that?

"have a look at these "Dir..." commands, it's what you need."

- i am familiar with the dir commands but i will read up on them a little more

Link to comment
Share on other sites

1. GUICtrlSetData WILL work - believe me :graduated:

2. You can make a "smart" thing to get around "frozen script":

- get the size of the folder to be backed up

- get a list of files and folders inside with their size (only level 1 - don't need to go to subfolders)

- think of an algorythm to update your progress bar according to these file/folder sizes being copied compared to the big folder size

- update the progress once a file (or folder) is copied.

You will have almost the same functionality as your original script but it will be much simple.

3. You got the idea, roughly that would be it.

Edited by enaiman

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Link to comment
Share on other sites

1. GUICtrlSetData WILL work - believe me :graduated:

2. You can make a "smart" thing to get around "frozen script":

- get the size of the folder to be backed up

- get a list of files and folders inside with their size (only level 1 - don't need to go to subfolders)

- think of an algorythm to update your progress bar according to these file/folder sizes being copied compared to the big folder size

- update the progress once a file (or folder) is copied.

You will have almost the same functionality as your original script but it will be much simple.

3. You got the idea, roughly that would be it.

sounds good to me buddy, work just got a little more busy out here so whenever i find time to get to it ill try to implement these changes, thanks again for the help i appreciate it.

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