Jump to content

Check if file exist and then take it from there...


Recommended Posts

I would like some comments on my script.

I am fresh into this, but Im here to learn!

And im really proud since this is the first script i have made all on my own!

But just give me your honest opinion, but keep in mind i am a newbie!

$filedir = @AppDataDir & "\Program" ;Directory within the Appdata directory where the ini file should be.
$filename = "test.ini" ;Ini file name.
$var = "variable";The name of the "has this script been ran before variable within the ini file. 0 = no, 1 = yes
$section = "section";The name of the section where the variable will be.


If FileExists($filedir) Then ;Check if the file directory exist.
    FileChangeDir($filedir) ;Go to the file directory.
    $read = IniRead($filename, $section, $var, "NotFound") ;Read the ini file.

Else
    DirCreate ($filedir) ;If file directory doesnt exist, create it.
EndIf

Func first()
    MsgBox (0,"First!", "First time you run this script") ;Code to execute when the script is run for the frist time.
    IniWrite ($filename, $section, $var, "1") ;Write that the script has been run into the ini file.
    Exit;Exit to avoid repetition.
EndFunc

Func second()
    MsgBox (0,"First!", "This script has been ran before");Code to excute whenever the script is ran for the second time.
    Exit;Exit to avoid repetition.
EndFunc


While 1
    If $read = 0 Then ;Checks if the script has been ran before, if not then call "first".
        Call ("first")
    Else ;If the script has been ran before it will call "second".
        Call("second")
    EndIf
WEnd

[font="helvetica, arial, sans-serif"]Hobby graphics artist, using gimp.Automating pc stuff, using AutoIt.Listening to music, using Grooveshark.[/font]Scripts:[spoiler]Simple ScreenshotSaves you alot of trouble when taking a screenshot!Don't remember what happened with this, but aperantly the exe is all i got.If you don't want to run it, simply don't._IsRun UDFIt figures out if the script has ben ran before based on the info in a ini file.If you don't want to use exactly what i wrote, you can use it as inspiration.[/spoiler]

Link to comment
Share on other sites

  • Replies 48
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

You have done extremely well for your first script! It took me quite some time to understand functions and make them work. You are also organized and are writing comments. Comments really help you remember why you did something. I comment all the time in my scripts.

I only have a couple suggestions:

Use more specific names for your variables and functions. You may have only called your functions 'first' and 'second' because it's just an example script. But in the future, if you want to re-use your code, having unique names from one program to the next will require less work integrating old code into new scripts.

I noticed that for your $read variable you assigned a default ini value of "NotFound". Later on, you used an If/Then statement to check $read against a value of "0". If it were me, I would either initialize $read to "NotFound" near the beginning of the script or have the default ini value to be "0". That's only to cover your bases in case something unexpected happens and either way, you will be covered on both sides. I know that may have sounded complicated. Maybe examples would help:

Either this:

$read = "NotFound"
...
$read = IniRead($filename, $section, $var, "NotFound")
...
 If $read = "NotFound" Then

OR

$read = 0
...
$read = IniRead($filename, $section, $var, "0")
...
 If $read = 0 Then

Keep up the good work!

#include <ByteMe.au3>

Link to comment
Share on other sites

Also don't use Call() instead call your functions directly

If $read = 0 Then ;Checks if the script has been ran before, if not then call "first".
        Call ("first")
    Else ;If the script has been ran before it will call "second".
        Call("second")
    EndIf

If $read = 0 Then ;Checks if the script has been ran before, if not then call "first".
        first()
    Else ;If the script has been ran before it will call "second".
        second()
    EndIf
Link to comment
Share on other sites

Why not use Call()? I know it is not necessary to use Call, but is there any reason not to use it? Does it use more resources or something?

You can use Call(), but you only need to use Call() when you want the extra conditional handling that Call() provides.

Imagine that _Call() in the example below is a lite version of what Call() does. Call() does extra error handling etc. which I will not go into to which adds overhead to process.

In this example, would you pick the direct UDF call at the top of the example or would you choose the substitute of Call() alias _Call()?

; direct UDF call
_Test()

;substitute Call() with UDF example
_Call('_Test')

Exit

Func _Call($function)
    Execute($function & '()')
EndFunc

Func _Test()
    MsgBox(0, '', 'Test')
EndFunc

I would choose the direct UDF call as the UDF is called direct. _Call() is a UDF, that calls a UDF. The later is unneeded overhead as 2 UDFs to do the same action as the direct UDF call. There is no reason to use more code handling then what is needed.

Edit:

@Maffe811

Do you get a "Variable used without being declared" error when the script is 1st run? As the declaration and assignment of $read only happens in the block of code which checks if $filedir exists.

Edited by MHz
Link to comment
Share on other sites

Why not use Call()? I know it is not necessary to use Call, but is there any reason not to use it? Does it use more resources or something?

As was said before: code overhead

and also possible problems with function's parameters and also obfuscation.

Call & Execute are functions only for specific purposes when name of function/code is not known at compile time and is generated at runtime, for example this function names: Test1, Test2, Test3, Test4, ... --> Call('Test' & $i)

Edited by Zedna
Link to comment
Share on other sites

Also don't use Call() instead call your functions directly

Okay, i didnt know you could do that.

I didnt know how to call a function and i found out you could use Call().

After reading the whole topic, i dont understand the difference between functionname(), Call() and _Call()

Use more specific names for your variables and functions. You may have only called your functions 'first' and 'second' because it's just an example script. But in the future, if you want to re-use your code, having unique names from one program to the next will require less work integrating old code into new scripts.

So, if the script want a login the first time i could call my function 'Log in' and 'Run script' ?

Basicly, make the names of things more individual ?

I noticed that for your $read variable you assigned a default ini value of "NotFound". Later on, you used an If/Then statement to check $read against a value of "0". If it were me, I would either initialize $read to "NotFound" near the beginning of the script or have the default ini value to be "0". That's only to cover your bases in case something unexpected happens and either way, you will be covered on both sides. I know that may have sounded complicated.

When i made this script, i mostly copied stuff from the help file and changed the variables and stuff.

When i ran the script i didnt have any errors with that, so i thought i did it right.

Ill go ahead and change notfound into 0.

Do you get a "Variable used without being declared" error when the script is 1st run? As the declaration and assignment of $read only happens in the block of code which checks if $filedir exists.

No, i do not, but i dont understand why i should either. Could you/someone explain it for me?

[font="helvetica, arial, sans-serif"]Hobby graphics artist, using gimp.Automating pc stuff, using AutoIt.Listening to music, using Grooveshark.[/font]Scripts:[spoiler]Simple ScreenshotSaves you alot of trouble when taking a screenshot!Don't remember what happened with this, but aperantly the exe is all i got.If you don't want to run it, simply don't._IsRun UDFIt figures out if the script has ben ran before based on the info in a ini file.If you don't want to use exactly what i wrote, you can use it as inspiration.[/spoiler]

Link to comment
Share on other sites

After reading the whole topic, i dont understand the difference between functionname(), Call() and _Call()

Call() is for special needs. _Call() is a user defined function (UDF) that I created for showing an example of how similar it can be to use Call() as being unsuitable for the task. I am not sure what functionname() exactly refers to that you mention.If you want to call a UDF then do so as Zedna has displayed.

No, i do not, but i dont understand why i should either. Could you/someone explain it for me?

Here is a trace of your script shown below.

1st the variables get processed and then goes to the FileExists line.

$filedir = @AppDataDir & "\Program" ;Directory within the Appdata directory where the ini file should be.
$filename = "test.ini" ;Ini file name.
$var = "variable";The name of the "has this script been ran before variable within the ini file. 0 = no, 1 = yes
$section = "section";The name of the section where the variable will be.


If FileExists($filedir) Then ;Check if the file directory exist.

FileExists() fails as no file on 1st run if found. So it goes to the else condition and continues processing.

Else
    DirCreate ($filedir) ;If file directory doesnt exist, create it.
EndIf

Func first()
    MsgBox (0,"First!", "First time you run this script") ;Code to execute when the script is run for the frist time.
    IniWrite ($filename, $section, $var, "1") ;Write that the script has been run into the ini file.
    Exit;Exit to avoid repetition.
EndFunc

Func second()
    MsgBox (0,"First!", "This script has been ran before");Code to excute whenever the script is ran for the second time.
    Exit;Exit to avoid repetition.
EndFunc


While 1
    If $read = 0 Then ;Checks if the script has been ran before, if not then call "first".
        Call ("first")
    Else ;If the script has been ran before it will call "second".
        Call("second")
    EndIf
WEnd

The 1st instance of $read seen by the interpreter is the use of $read being compared to zero. Since it has been used with out being declared or assigned previous, then a "Variable used without being declared" error occurs. It is the error that I received on 1st run. Delete the "Program" folder in the "%AppData%" directory and try to run your script again. Or add the below code just before your FileExists() condition to remove the folder so it will seem like a 1st run.

DirRemove($filedir, 1)
Link to comment
Share on other sites

I kinda fell overboard here.

If FileExists() fails, then it creates the directory.

So either the directory exists or it is created!

And the functionname() was just a random funcition name, like:

Func fucntionname()

The second version:

$filedir = @AppDataDir & "\Program" ;Directory within the Appdata directory where the ini file should be.
$filename = "test.ini" ;Ini file name.
$var = "variable";The name of the "has this script been ran before variable within the ini file. 0 = no, 1 = yes
$section = "section";The name of the section where the variable will be.
$read = 0;Declare the read variable and set it to 0

If FileExists($filedir) Then ;Check if the file directory exist.
    FileChangeDir($filedir) ;If it exists, go to the file directory.
    $read = IniRead($filename, $section, $var, 0) ;Read the ini file, if nothing found $read = 0.

Else
    DirCreate ($filedir) ;If file directory doesnt exist, create it.
EndIf

Func first()
    MsgBox (0,"First!", "First time you run this script") ;Code to execute when the script is run for the frist time.
    IniWrite ($filename, $section, $var, "1") ;Write that the script has been run into the ini file.
    Exit;Exit to avoid repetition.
EndFunc

Func second()
    MsgBox (0,"Not new", "This script has been ran before");Code to excute whenever the script is ran for the second time.
    Exit;Exit to avoid repetition.
EndFunc


While 1
    If $read = 0 Then ;Checks if the script has been ran before, if not then call "first".
        first ()
    Else ;If the script has been ran before it will call "second".
        second()
    EndIf
WEnd

Changes:

- Declaring the $read variable at the top

- Way of calling functions changed

- Fixed a fail with the messagebox

How do you write an UDF?

Does an UDF like this exist?

[font="helvetica, arial, sans-serif"]Hobby graphics artist, using gimp.Automating pc stuff, using AutoIt.Listening to music, using Grooveshark.[/font]Scripts:[spoiler]Simple ScreenshotSaves you alot of trouble when taking a screenshot!Don't remember what happened with this, but aperantly the exe is all i got.If you don't want to run it, simply don't._IsRun UDFIt figures out if the script has ben ran before based on the info in a ini file.If you don't want to use exactly what i wrote, you can use it as inspiration.[/spoiler]

Link to comment
Share on other sites

...

And the functionname() was just a random funcition name, like:

Func fucntionname()

Ah, thanks. The "Func fucntionname()" is the start of the UDF. Between the Func and EndFunc keywords is the UDF code which is user added code for the function thus it is called a user defined function. Your Func first() ... EndFunc code block is a user defined function and you call it with first().

Changes:

- Declaring the $read variable at the top

- Way of calling functions changed

- Fixed a fail with the messagebox

How do you write an UDF?

Does an UDF like this exist?

Very good changes. Now, you already wrote 2 UDFs in your script as explained above.

As for a UDF, your code could be added into a UDF. Below is a UDF I just created though your code seems OK now.

If _AppDataIniSettings('Program', 'test.ini', 'section', 'variable', '1', True) Then
    If @extended Then MsgBox(0, 'Write', '1st run of ' & @ScriptName)
EndIf

; last 2 parameters are optional and have nothing to do with reading the ini file
$value = _AppDataIniSettings('Program', 'test.ini', 'section', 'variable')
If Not @error Then
    MsgBox(0, 'Read', '$value = ' & $value)
EndIf

Func _AppDataIniSettings($folder, $inifile, $section, $key, $value = '', $write = False)
    Local $firstrun = 0
    If $write Then
        ; check if folder exists. if not, create it
        If Not FileExists(@AppDataDir & '\' & $folder) Then
            $firstrun = 1; set variable for 1st run status
            If Not DirCreate(@AppDataDir & '\' & $folder) Then
                ; failed to create the folder, set @error and return
                Return SetError(1, $firstrun, 0)
            EndIf
        EndIf
        ; write the ini file
        If IniWrite(@AppDataDir & '\' & $folder & '\' & $inifile, $section, $key, $value) Then
            ; return 1 for success
            Return SetError(0, $firstrun, 1)
        Else
            ; failed to write to the ini file, set @error and return
            Return SetError(2, $firstrun, 0)
        EndIf
    Else
        ; read the ini file
        Return IniRead(@AppDataDir & '\' & $folder & '\' & $inifile, $section, $key, '')
    EndIf
EndFunc
Link to comment
Share on other sites

Ah, okay!

But i was thinking as if my script could be written to be in the #include thing.

So at the top of the script you write:

#Include MyScript

MyScriptSettings("Filedirectory", "filename", "Section", "key")

Then you can use that in your scripts to find out if the program has been run before

$key = MyScriptSettings(@appdatadir & "\MyScript", "test.ini", "test", "test")

then $key would return 0 if its the first time and 1 if the program has been ran before.

[font="helvetica, arial, sans-serif"]Hobby graphics artist, using gimp.Automating pc stuff, using AutoIt.Listening to music, using Grooveshark.[/font]Scripts:[spoiler]Simple ScreenshotSaves you alot of trouble when taking a screenshot!Don't remember what happened with this, but aperantly the exe is all i got.If you don't want to run it, simply don't._IsRun UDFIt figures out if the script has ben ran before based on the info in a ini file.If you don't want to use exactly what i wrote, you can use it as inspiration.[/spoiler]

Link to comment
Share on other sites

At the top of your #include script, add the directive #include-once. The #include-once prevents AutoIt including the same script more then once. Then add you user defined functions into the #include script.

So your #include script looks like this

#include-once

Func MyScriptSettings()
    ; some code here
EndFunc

And your main script is something like this

#Include "MyScript.au3"

MyScriptSettings("Filedirectory", "filename", "Section", "key")

$key = MyScriptSettings(@appdatadir & "\MyScript", "test.ini", "test", "test")

Your UDF can be setup to return 0 for 1st run, but it is not what I would do. That is why I chose to use @extended set by using SetError() as the flag of whether 1st run happened. The return value I set is used as a test for use with the If...Then condition.

Link to comment
Share on other sites

Your UDF can be setup to return 0 for 1st run, but it is not what I would do. That is why I chose to use @extended set by using SetError() as the flag of whether 1st run happened. The return value I set is used as a test for use with the If...Then condition.

i read the help file, and i didnt really understand what @extended or SetError() does... neither did i understand how it can help...

Can you explain ?

Edited by Maffe811

[font="helvetica, arial, sans-serif"]Hobby graphics artist, using gimp.Automating pc stuff, using AutoIt.Listening to music, using Grooveshark.[/font]Scripts:[spoiler]Simple ScreenshotSaves you alot of trouble when taking a screenshot!Don't remember what happened with this, but aperantly the exe is all i got.If you don't want to run it, simply don't._IsRun UDFIt figures out if the script has ben ran before based on the info in a ini file.If you don't want to use exactly what i wrote, you can use it as inspiration.[/spoiler]

Link to comment
Share on other sites

SetError() can set the @error macro after a function call to show a non zero result to be interpreted as an error condition. SetError() also does optional @extended value and optional return value. @extended can hold a set integer value for whatever purpose that you like.

Here is an example of setting, getting and using the error, extended and return value from a function.

$return_value = _Test() ;  GET return value
$error = @error ;  GET error value and save
$extended = @extended ;  GET extended value and save

MsgBox(0x40, _
        'Value of all variables', _
        '$return_value = ' & $return_value & @CRLF & _
        '$error = ' & $error & @CRLF & _
        '$extended = ' & $extended _
)

If $return_value Then
    ;  USE return value code here
    MsgBox(0x40, 'If $return_value Then', 'Variable $return_value = ' & $return_value)
EndIf

If $error Then
    ;  USE error handling code here
    MsgBox(0x30, 'If $error Then', 'Variable $error = ' & $error)
EndIf

If $extended Then
    ;  USE extended code here
    MsgBox(0x40, 'If $extended Then', 'Variable $extended = ' & $extended)
EndIf

;  USE all conditions that were set or returned from the _Test() function
If $error Then
    MsgBox(0x30, 'Test Report', 'We found an error with function processing. Code = ' & $error)
ElseIf $return_value Then
    MsgBox(0x40, _
            'Test Report', _
            'Function was successful' & @CRLF & _
            '$return_value = ' & $return_value & @CRLF & _
            '$extended = ' & $extended & @CRLF & _
            'We caught ' & $extended & ' large ' & $return_value _
        )
Else
    MsgBox(0x40, 'Test Report', 'Nothing to report')
EndIf

Exit

Func _Test()
    ;  Local variables only exist in the function while the function is running
    Local $return_value
    ;  set local $error  value 0 or 1
    Local $error = Random(0, 1, True)
    ;  set local $extended  value from 0 to 10
    Local $extended = Random(0, 10, True)
    ; if $error is 0, then $return_value is "fish", else consider something failed
    If Not $error Then $return_value = 'fish'
    ; SET error status, extended status and a return value
    Return SetError($error, $extended, $return_value)
EndFunc

Run it multiple times to see it handle different changes.

Lets look at some basic function handling.

To set and get a return value

$return_value = _Test()
MsgBox(0, '', $return_value)

Func _Test()
    Return 'string'
EndFunc

If your function does not have a need for a return value then you can have it return success or failure. Something returned can be regarded as success in this example

If _Test() Then
    MsgBox(0, '', 'Success')
EndIf

Func _Test()
    Return True
EndFunc

Lets try the SetError() to set the @error macro for us to show an error condition has happened

_Test()
If @error Then
    MsgBox(0, '', '@error = ' & @error)
EndIf

Func _Test()
    Return SetError(1)
EndFunc

Now lets try using @error = 0, which is non error and set @extended to something and lets set a return value as well.

$return_value = _Test()
If Not @error Then
    MsgBox(0, '', '@extended = ' & @extended)
    MsgBox(0, '', '$return_value = ' & $return_value)
EndIf

Func _Test()
    Return SetError(0, 5, 'I like showing data')
EndFunc

In the later example, just like in the code I provided in the previous post uses the return value and sets the @error macro so using @extended as a means to show success was all that was left. The option to return more info is to return an array.

Link to comment
Share on other sites

So SetError let's you controll what the error messge would be?

Not 100% sure what return does... Is it basicly returning a value to who-/whatever asked for it ?

And im still totaly lost on extended.

But how would i incorporate this into my script?

I must be sick or something cause i dont understand nothing.

[font="helvetica, arial, sans-serif"]Hobby graphics artist, using gimp.Automating pc stuff, using AutoIt.Listening to music, using Grooveshark.[/font]Scripts:[spoiler]Simple ScreenshotSaves you alot of trouble when taking a screenshot!Don't remember what happened with this, but aperantly the exe is all i got.If you don't want to run it, simply don't._IsRun UDFIt figures out if the script has ben ran before based on the info in a ini file.If you don't want to use exactly what i wrote, you can use it as inspiration.[/spoiler]

Link to comment
Share on other sites

well return is used at the end of a function. so you can do somthing like this

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 404, 177, 552, 161)
$Input1 = GUICtrlCreateInput("Input1", 48, 32, 185, 21)
$Button1 = GUICtrlCreateButton("Button1", 96, 72, 75, 25, $WS_GROUP)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button1
            If _check() = 1 Then
                MsgBox(0, "title", "good job:)")
            Else
                MsgBox(0, "Error", "please enter *String* in the input box")
            EndIf
    EndSwitch
WEnd

Func _check()
    $read = GUICtrlRead($Input1)
    If $read = "string" Then
        Return 1
    Else
        Return 0
    EndIf
EndFunc

this checks if the input box reads string and if it does then it returns 1, if it doesn't then it returns 0 which is the error.

[spoiler]My UDFs: Login UDF[/spoiler]

Link to comment
Share on other sites

so you can use a function to calculate something and then return to asign that value to the function ?

Crappy on the fly coding:

Calc()
MsgBox (0,"Statement", "The statement is" & _Calc())

Func _Calc()
If 2 + 2 = 4 Then
Return True
Else
Return False
EndFunc

I dont know if you understand, and its probably missing a vital part, but do you get my point ?

Edited by Maffe811

[font="helvetica, arial, sans-serif"]Hobby graphics artist, using gimp.Automating pc stuff, using AutoIt.Listening to music, using Grooveshark.[/font]Scripts:[spoiler]Simple ScreenshotSaves you alot of trouble when taking a screenshot!Don't remember what happened with this, but aperantly the exe is all i got.If you don't want to run it, simply don't._IsRun UDFIt figures out if the script has ben ran before based on the info in a ini file.If you don't want to use exactly what i wrote, you can use it as inspiration.[/spoiler]

Link to comment
Share on other sites

yah you understand it. but you can also put the function into a variable to. so this:

_Calc()
MsgBox (0,"Statement", "The statement is" & _Calc())

Func _Calc()
If 2 + 2 = 4 Then
Return True
Else
Return False
EndIf
EndFunc

is the same as this:

$var = _Calc()
MsgBox (0,"Statement", "The statement is" & $var)

Func _Calc()
If 2 + 2 = 4 Then
Return True
Else
Return False
EndIf
EndFunc

[spoiler]My UDFs: Login UDF[/spoiler]

Link to comment
Share on other sites

So by adding return, the function can be used as a variable ?

[font="helvetica, arial, sans-serif"]Hobby graphics artist, using gimp.Automating pc stuff, using AutoIt.Listening to music, using Grooveshark.[/font]Scripts:[spoiler]Simple ScreenshotSaves you alot of trouble when taking a screenshot!Don't remember what happened with this, but aperantly the exe is all i got.If you don't want to run it, simply don't._IsRun UDFIt figures out if the script has ben ran before based on the info in a ini file.If you don't want to use exactly what i wrote, you can use it as inspiration.[/spoiler]

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