Sign in to follow this  
Followers 0
benners

Functions and Variables

9 posts in this topic

I am making a script that allows the backing up of folder\files and registry settings and have hit a block. It may be apparent to someone whom knows what they are doing but not I.

In the script I call a function and a variable is created which is an integer based on the number of actions found in an ini file. I have an error function that writes to a log and part of the text contains the variable, everything seems ok except that the variable created in one function is not available to the other, I have declared the variable as global but have a feeling that as I obviously don't know what I am doing I am making a universally dumb mistake :">

Any help is appreciated as are cleaner ways to write the script and bitch slaps for bad practice.

#NoTrayIcon ; Don't show a tray icon whilst running.

Dim $Ini = @ScriptDir & "\backup.ini" ; Set the ini file location.
Dim $Action, $Actions, $Dest, $ErrMsg, $Section, $Source, $String, $Ini
Dim $Backup, $CurrentTotal = 0, $CurrentUserPic, $SectionLbl, $ErrLbl, $SourceInp, $DestInp, $CurrentProgressLbl, $TotalProgressLbl, $CurrentProgressBar, $TotalProgressBar
Global $var, $i
Global Const $SS_NOTIFY = 0x0100
Global Const $WS_GROUP = 0x00020000
Global Const $SS_CENTER = 1
Global Const $SS_CENTERIMAGE = 0x0200
Global Const $ES_READONLY = 2048
Global Const $ES_AUTOHSCROLL = 128
Global Const $BackupDir = IniRead($Ini, @UserName, "BackupDir", "D:\Programs") ; Set the default backup location.
Global Const $TotalActions = (IniRead($Ini, "Global", "Dir", "") + IniRead($Ini, "Global", "File", "") + IniRead($Ini, "Global", "Registry", "") + IniRead($Ini, @UserName, "Dir", "") + IniRead($Ini, @UserName, "File", "") + IniRead($Ini, @UserName, "Registry", ""))
Global Const $ErrLog = @TempDir & "\BackupError.txt"

If FileExists($ErrLog) Then FileDelete($ErrLog) ; If a previous error log exists, then delete it.

; Draw GUI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$Backup = GUICreate("Backup", 547, 315, -1, -1)
GUICtrlCreateGroup("Current User ", 8, 16, 185, 73)
$CurrentUserPic = GUICtrlCreatePic(@AppDataCommonDir & "\Microsoft\User Account Pictures\" & @UserName & ".bmp", 120, 32, 48, 48, BitOR($SS_NOTIFY, $WS_GROUP))
GUICtrlCreateLabel(@UserName, 16, 40, 75, 28)
GUICtrlSetFont(-1, 14, 400, 0, "MS Sans Serif")
GUICtrlCreateGroup("Section ", 216, 16, 161, 73)
$SectionLbl = GUICtrlCreateLabel("Waiting...", 224, 40, 147, 28, $SS_CENTER)
GUICtrlSetFont(-1, 14, 400, 0, "MS Sans Serif")
GUICtrlCreateGroup("Selection ", 8, 96, 529, 97)
GUICtrlCreateLabel("Source ...", 16, 120, 50, 17, $SS_CENTERIMAGE)
GUICtrlCreateGroup("Errors ", 400, 16, 65, 73)
$ErrLbl = GUICtrlCreateLabel("0", 406, 40, 49, 28, $SS_CENTER)
GUICtrlSetFont(-1, 14, 400, 0, "MS Sans Serif")
$SourceInp = GUICtrlCreateInput("", 72, 120, 449, 21, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
GUICtrlSetBkColor(-1, 0xffffff)
GUICtrlCreateLabel("Dest ...", 16, 152, 38, 17, $SS_CENTERIMAGE)
$DestInp = GUICtrlCreateInput("", 72, 152, 449, 21, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
GUICtrlSetBkColor(-1, 0xffffff)
GUICtrlCreateGroup("", -99, -99, 1, 1)
GUICtrlCreateGroup("Progress ", 8, 200, 529, 105)
$CurrentProgressLbl = GUICtrlCreateLabel("Current Action: Waiting... ", 16, 216, 510, 15)
$CurrentProgressBar = GUICtrlCreateProgress(16, 235, 510, 17)
GUICtrlSetColor(-1, 0x3B97D3)
$TotalProgressLbl = GUICtrlCreateLabel("Total Actions: 0", 16, 256, 510, 15)
$TotalProgressBar = GUICtrlCreateProgress(16, 272, 510, 17)
GUICtrlSetColor(-1, 0x3B97D3)
GUISetState(@SW_SHOW)

; Copy the Global directories.
$Section = "Global"
GUICtrlSetData($SectionLbl, $Section) ; Update the section label text.
$Action = "Dir"
DoAction()

; Copy the Global files.
$Action = "File"
DoAction()

; Export the Global registry.
$Action = "Registry"
DoAction()

If IniReadSection($Ini, @UserName) = 1 Then                            ; If there is no section for the current user,
    $ErrMsg = "No section available for the current user " & @UserName ; Set the error message.
    WriteError()                                                       ; Write the error to the log.
    MsgBox(64, "Error Log", GUICtrlRead($ErrLbl) & " Error(s) Occured, Please see log for details" & @CRLF & $ErrLog, 5)
    Exit
EndIf

; Copy the Users directories.
$Section = @UserName
GUICtrlSetData($SectionLbl, $Section) ; Update the section label text.
$Action = "Dir"
DoAction()

; Copy the Users files.
$Action = "File"
DoAction()

; Export the Users registry.
$Action = "Registry"
DoAction()

; Inform the user of the errors.
If GUICtrlRead($ErrLbl) <> 0 Then MsgBox(64, "Error Log", GUICtrlRead($ErrLbl) & " Error(s) Occured, Please read log for details", 5)
Exit

Func DoAction()

    $Actions = IniRead($Ini, $Section, $Action, "") ; Get the number of file\folder\registry actions.
    If $Actions = "" Then MsgBox(16, "Error", "Unable to copy selected " & $Action & "(s) as " & $Action & " parameter is missing", 5) ; If the actions value is blank then show an error.
    If $Actions = "0" Then Return ; If the actions value is zero then ignore.
    
    For $i = 1 To $Actions
        $String = StringReplace(IniRead($Ini, $Section, $Action & $i, ""), "#appdata#", @AppDataDir) ; Replace instances of appdata with @AppDataDir.
        $String = StringReplace($String, "#backup#", $BackupDir)                                     ; Replace instances of backup with location of users backup directory.
        $var = StringSplit($String, ",")                                                             ; Split the string into source and destination var.
        $CurrentTotal = $CurrentTotal + 1                                                            ; Increment the current total.
        
        Select
            Case $Action = "Dir"

                ErrorCheck()
                
                If FileExists($var[2]) Then DirRemove($var[2], 1)                                                         ; If the destination exists, delete it.
                GUICtrlSetData($SourceInp, $var[1])                                                                       ; Set the SourceInput text.
                GUICtrlSetData($DestInp, $var[2])                                                                         ; Set the DestInput text.
                GUICtrlSetData($CurrentProgressLbl, "Current Action: Copying " & $Action & " " & $i & " of " & $Actions)  ; Set the text for the current action.
                GUICtrlSetData($CurrentProgressBar, Int(100 / $Actions * $i))                                             ; Set the progress of the current actions.
                GUICtrlSetData($TotalProgressLbl, "Total Actions: " & $CurrentTotal & " of " & $TotalActions)             ; Set the text for the total number of actions.
                GUICtrlSetData($TotalProgressBar, Int(100 / $TotalActions * $CurrentTotal))                               ; Set the progress of the total number of actions.
                DirCopy($var[1], $var[2], 1)                                                                              ; Copy the selected directories, overwriting if required.
                
            Case $Action = "File"

                ErrorCheck()
                
                If StringRight($var[2], 1) <> "\" Then $var[2] = $var[2] & "\"                                           ; If the destination directory doesn't have a trailing backslash, add one, required for copy path.
                GUICtrlSetData($SourceInp, $var[1])                                                                      ; Set the SourceInput text.
                GUICtrlSetData($DestInp, $var[2])                                                                        ; Set the DestInput text.
                GUICtrlSetData($CurrentProgressLbl, "Current Action: Copying " & $Action & " " & $i & " of " & $Actions) ; Set the text for the current action.
                GUICtrlSetData($CurrentProgressBar, Int(100 / $Actions * $i))                                            ; Set the progress of the current actions.
                GUICtrlSetData($TotalProgressLbl, "Total Actions: " & $CurrentTotal & " of " & $TotalActions)            ; Set the text for the total number of actions.
                GUICtrlSetData($TotalProgressBar, Int(100 / $TotalActions * $CurrentTotal))                              ; Set the progress of the total number of actions.
                FileCopy($var[1], $var[2], 9)                                                                            ; Copy the files, overwriting and creating dir structure if required.
                
            Case $Action = "Registry"
                
                GUICtrlSetData($SourceInp, $var[1])                                                                        ; Set the SourceInput text.
                GUICtrlSetData($DestInp, $var[2])                                                                          ; Set the DestInput text.
                GUICtrlSetData($CurrentProgressLbl, "Current Action: Exporting " & $Action & " " & $i & " of " & $Actions) ; Set the text for the current action.
                GUICtrlSetData($CurrentProgressBar, Int(100 / $Actions * $i))                                              ; Set the progress of the current actions.
                GUICtrlSetData($TotalProgressLbl, "Total Actions: " & $CurrentTotal & " of " & $TotalActions)              ; Set the text for the total number of actions.
                GUICtrlSetData($TotalProgressBar, Int(100 / $TotalActions * $CurrentTotal))                                ; Set the progress of the total number of actions.
                RunWait("Reg Export " & '"' & $var[1] & '"' & " " & '"' & $var[2] & '"', "", @SW_HIDE)                     ; Export the registry keys.
        EndSelect
    Next
    
EndFunc   ;==>DoAction

Func ErrorCheck()

    If $var[1] = "" Then ; If the source string is blank
        $ErrMsg = "<ERROR> - Missing Source Entry - Section = " & $Section & ", Action = " & $Action & $i ; Set the error message.
        WriteError() ; Write the error to the log.
        Return (1)   ; Skip current action and Run the next action.
    EndIf
    
    If Not FileExists($var[1]) Then ; If the source doesn't exist.
        $ErrMsg = "<ERROR> - Missing Source Folder - Section = " & $Section & ", Action  = " & $Action & $i & ", Source = " & $var[1] ; Set the error message.
        WriteError() ; Write the error to the log.
        Return (1)   ; Skip current action and Run the next action.
    EndIf
    
    If $var[1] = $var[2] Then ; If the source and destination are the same.
        $ErrMsg = "<ERROR> - Source And Destination Are The Same - Section = " & $Section & ", Action  = " & $Action & $i & ", Source = " & $var[1] & ", Dest = " & $var[2] ; Set the error message.
        WriteError() ; Write the error to the log.
        Return (1)   ; Skip current action and Run the next action.
    EndIf
    
EndFunc   ;==>ErrorCheck

Func WriteError()
    
    GUICtrlSetColor($ErrLbl, 0xff0000)                ; Set the text colour of the error label to Red.
    GUICtrlSetData($ErrLbl, GUICtrlRead($ErrLbl) + 1) ; Increase the error count by 1 & set the text of the error label.
    $File = FileOpen($ErrLog, 1)                      ; Open an errorlog file.
    FileWrite($ErrLog, $ErrMsg & @CRLF)               ; Write (append) a line to it.
    FileClose($ErrLog)                                ; Close the file.
    
EndFunc   ;==>WriteError

Share this post


Link to post
Share on other sites



I am making a script that allows the backing up of folder\files and registry settings and have hit a block. It may be apparent to someone whom knows what they are doing but not I.

In the script I call a function and a variable is created which is an integer based on the number of actions found in an ini file. I have an error function that writes to a log and part of the text contains the variable, everything seems ok except that the variable created in one function is not available to the other, I have declared the variable as global but have a feeling that as I obviously don't know what I am doing I am making a universally dumb mistake :">

Any help is appreciated as are cleaner ways to write the script and bitch slaps for bad practice.

Which variable and which function sets its value, then which fuction does not see it? :P


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

DOH!, sorry my bad :"> . The variable is $i, it is created by the DoAction() function and should equate to an number. The number is read from the ini file (posted below) and sets the number of time to perfom the copying or exporting loop.

The function is ErrorCheck(), this function creates a variable called $ErrMsg and passes it to another function that writes the error to the text file, I'll probably combine the two error functions if I can when everything is working. The Error message should read something like

<ERROR> - Missing Source Entry - Section = Benners, Action = Dir1
but the $i is not added and reads
<ERROR> - Missing Source Entry - Section = Benners, Action = Dir
here is the ini
[Global]
Dir=2
Dir1=#appdata#\Mozilla,#backup#\Mozilla
Dir2=#appdata#\thunderbird,#backup#\Mozilla\Thunderbird
File=0
Registry=0

[Benners]
BackupDir=D:\Programs
Dir=1
Dir1=C:\Program Files\Mozilla Firefox\searchplugins,#backup#\Mozilla\searchplugins
File=1
File1=#appdata#\MailWasherPro\*.txt,#backup#\Mailwasher
Registry=1
Registry1=HKEY_CURRENT_USER\Software\FireTrust,#backup#\Mailwasher\settings.reg

Thanks

Share this post


Link to post
Share on other sites

DOH!, sorry my bad :"> . The variable is $i, it is created by the DoAction() function and should equate to an number. The number is read from the ini file (posted below) and sets the number of time to perfom the copying or exporting loop.

The function is ErrorCheck(), this function creates a variable called $ErrMsg and passes it to another function that writes the error to the text file, I'll probably combine the two error functions if I can when everything is working. The Error message should read something like

<ERROR> - Missing Source Entry - Section = Benners, Action = Dir1
but the $i is not added and reads
<ERROR> - Missing Source Entry - Section = Benners, Action = Dir
here is the ini
[Global]
Dir=2
Dir1=#appdata#\Mozilla,#backup#\Mozilla
Dir2=#appdata#\thunderbird,#backup#\Mozilla\Thunderbird
File=0
Registry=0

[Benners]
BackupDir=D:\Programs
Dir=1
Dir1=C:\Program Files\Mozilla Firefox\searchplugins,#backup#\Mozilla\searchplugins
File=1
File1=#appdata#\MailWasherPro\*.txt,#backup#\Mailwasher
Registry=1
Registry1=HKEY_CURRENT_USER\Software\FireTrust,#backup#\Mailwasher\settings.reg

Thanks

No, relying on Global variables to hold everything is not "passing" the data to the functions. To pass it do the following:

Change your calls to ErrorCheck() to look like this:

ErrorCheck($i)oÝ÷ Ù8^ÈZ­á+®Âç$~éܶ*'ÛùbëaÆ®¶­sdgVæ2W'&÷$6V6²b33c¶çVÒ ¢bb33c·f%³ÒÒgV÷C²gV÷C²FVâ²bFR6÷W&6R7G&ær2&Ææ°¢b33c´W'$×6rÒgV÷C²fÇC´U%$õ"fwC²ÒÖ76ær6÷W&6RVçG'Ò6V7FöâÒgV÷C²fײb33cµ6V7FöâfײgV÷C²Â7FöâÒgV÷C²fײb33c´7Föâfײb33c¶çVÒ²6WBFRW'&÷"ÖW76vRà¢w&FTW'&÷"²w&FRFRW'&÷"FòFRÆörà¢&WGW&â²6¶7W'&VçB7FöâæB'VâFRæWB7Föâà¢VæD`¢¢bæ÷BfÆTW7G2b33c·f%³ÒFVâ²bFR6÷W&6RFöW6âb33·BW7Bà¢b33c´W'$×6rÒgV÷C²fÇC´U%$õ"fwC²ÒÖ76ær6÷W&6RföÆFW"Ò6V7FöâÒgV÷C²fײb33cµ6V7FöâfײgV÷C²Â7FöâÒgV÷C²fײb33c´7Föâfײb33c¶çVÒfײgV÷C²Â6÷W&6RÒgV÷C²fײb33c·f%³Ò²6WBFRW'&÷"ÖW76vRà¢w&FTW'&÷"²w&FRFRW'&÷"FòFRÆörà¢&WGW&â²6¶7W'&VçB7FöâæB'VâFRæWB7Föâà¢VæD`¢¢bb33c·f%³ÒÒb33c·f%³%ÒFVâ²bFR6÷W&6RæBFW7FæFöâ&RFR6ÖRà¢b33c´W'$×6rÒgV÷C²fÇC´U%$õ"fwC²Ò6÷W&6RæBFW7FæFöâ&RFR6ÖRÒ6V7FöâÒgV÷C²fײb33cµ6V7FöâfײgV÷C²Â7FöâÒgV÷C²fײb33c´7Föâfײb33c¶çVÒfײgV÷C²Â6÷W&6RÒgV÷C²fײb33c·f%³ÒfײgV÷C²ÂFW7BÒgV÷C²fײb33c·f%³%Ò²6WBFRW'&÷"ÖW76vRà¢w&FTW'&÷"²w&FRFRW'&÷"FòFRÆörà¢&WGW&â²6¶7W'&VçB7FöâæB'VâFRæWB7Föâà¢VæD`¢¤VæDgVæ2³ÓÒfwC´W'&÷$6V6

Cheers!

:P


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

Thanks PsaltyDS that worked, but you prolly knew that. I had tried to use the ErrorCheck($i) before but for the ErrorCheck() function I had mistakenly used

ErrorCheck(ByRef $i)
but after reading the help I assume the ByRef is only used for arrays.

Could you please explain the $iNum part, I may have to pass string info later on and would like to do it correctly, is the $iNum classed as an optional parameter? and do you use Num due to the fact that it would be and integer?

Many Thanks

Share this post


Link to post
Share on other sites

Func WriteError()
    
    GUICtrlSetColor($ErrLbl, 0xff0000)                ; Set the text colour of the error label to Red.
    GUICtrlSetData($ErrLbl, GUICtrlRead($ErrLbl) + 1) ; Increase the error count by 1 & set the text of the error label.
    $File = FileOpen($ErrLog, 1)                      ; Open an errorlog file.
    FileWrite($ErrLog, $ErrMsg & @CRLF)               ; Write (append) a line to it.
    FileClose($ErrLog)                                ; Close the file.
    
EndFunc   ;==>WriteError
You may want to close the handle $file, not the file name.

Share this post


Link to post
Share on other sites

You may want to close the handle $file, not the file name.

Nice catch, Thanks MHz, also using Select Case instead of If's and EndIf's in the ErrorCheck() function.

Share this post


Link to post
Share on other sites

Thanks PsaltyDS that worked, but you prolly knew that. I had tried to use the ErrorCheck($i) before but for the ErrorCheck() function I had mistakenly used

ErrorCheck(ByRef $i)
but after reading the help I assume the ByRef is only used for arrays.

Could you please explain the $iNum part, I may have to pass string info later on and would like to do it correctly, is the $iNum classed as an optional parameter? and do you use Num due to the fact that it would be and integer?

Many Thanks

You're on the right track, but a little off on ByRef.

When you declare the fuction, you specify the LOCAL variable that the fuction will use to refer to the data that was passed to it. So inside the ErrorCheck() function, it sees that number as $iNum.

When you call the function you can use ANY variable or a literal in the call. These would all be valid calls to ErrorCheck():

ErrorCheck(5)
ErrorCheck($i)
ErrorCheck($j)
ErrorCheck($k)
ErrorCheck($MyVar)
ErrorCheck(20 + $i / 2)
ErrorCheck($MyArray[$i])

Hope that helps! :P


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

Thanks again PsaltyDS, your explanation makes it a lot clearer, now if you could just rewrite the help file....... :P

Share this post


Link to post
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
Sign in to follow this  
Followers 0