Jump to content


Photo

Auto read,load and save an INI file Updated....


  • Please log in to reply
24 replies to this topic

#1 Superfraggle

Superfraggle
  • Members
  • 1019 posts

Posted 20 July 2007 - 09:30 PM

Engunneer said something like this had been done before but I thought I would make my own attempt for practice.

We have three functions

initializeini()
loadini()
saveini()

initializeini will read the specified INI file and load all section and key names.

loadini will then load all the associated keys and assign them to variables of section_keyname.

Saveini will save all variables to the correct section & key.

You can either specify the name of the inifile in the function call, or specify it within the function (for lazy programmers)

This could be used as part of a template to help you along the way of creating more customizable apps.

Heres the code for the functions.

initializeini(inifile = "ast.ini"){
  global
  local key,temp
  inisections:=0
 
  loop,read,%inifile%
  {
    if regexmatch(A_Loopreadline,"\[(.*)?]")
      {
        inisections+= 1
        section%inisections%:=regexreplace(A_loopreadline,"(\[)(.*)?(])","$2")
        section%inisections%_keys:=0
      }
    else if regexmatch(A_LoopReadLine,"(\w+)=(.*)")
      {
        section%inisections%_keys+= 1
        key:=section%inisections%_keys
        section%inisections%_key%key%:=regexreplace(A_LoopReadLine,"(\w+)=(.*)","$1")
      }
  }
}

loadini(inifile="ast.ini"){
  global
  local sec,var
  loop,%inisections%
    {
      sec:=A_index
      loop,% section%a_index%_keys
        {
          var:=section%sec% "_" section%sec%_key%A_index%,
          Stringreplace,var,var,%a_space%,,All
          iniread,%var%,%inifile%,% section%sec%,% section%sec%_key%A_index%
        }
    }
}

saveini(inifile="ast.ini"){
  global
  local sec,var
  loop,%inisections%
    {
      sec:=A_index
      loop,% section%a_index%_keys
        {
          var:=section%sec% "_" section%sec%_key%A_index%
          Stringreplace,var,var,%a_space%,,All
          var:=%var%
          iniwrite,%var%,%inifile%,% section%sec%,% section%sec%_key%A_index%
        }
    }
}


As always comments and suggestions welcome

Update:

Code has been slightly updated to work with spaces in keys, and section names.

#2 HuBa

HuBa
  • Members
  • 175 posts

Posted 21 July 2007 - 11:19 PM

Why is the filename (ast2.ini) different in save then in read?

#3 Superfraggle

Superfraggle
  • Members
  • 1019 posts

Posted 22 July 2007 - 12:37 AM

My bad that was used for testing, just in case it ddidn't work I didn't want to mess up my ini file.

They can be changed to whatever you want anyway, or specify the filename in the function call.

#4 Superfraggle

Superfraggle
  • Members
  • 1019 posts

Posted 27 August 2007 - 08:48 PM

I've updated the code slightly as there was a bug that wasn't detected in my version of AHK.

#5 WankaUSR

WankaUSR
  • Members
  • 87 posts

Posted 07 September 2007 - 01:55 PM

First of all i'm o newbie so don't laugh ...
How do i call this functions... for example if i want to make the call at the beginning of the script and save at exitapp or button press?

#6 Superfraggle

Superfraggle
  • Members
  • 1019 posts

Posted 07 September 2007 - 04:09 PM

We don't laugh at new people.

To call the function on exit best to use the following.

onexit, close ; Put this at the very start of the script. 

; put this after the autoexecute section of the script. 
Close:
saveini()
exitapp
return

if you have a gui with a save button, then it would be something like

buttonsave:
saveini()
return

Be sure to change the name of the inifile you are actually using in the original function.

#7 Guests

  • Guests

Posted 07 September 2007 - 05:04 PM

thanks this helped me a lot by reducing the script size for reading and writing inis

#8 WankaUSR

WankaUSR
  • Members
  • 87 posts

Posted 07 September 2007 - 05:06 PM

This is what i've really needed thanks an keep up the good work
So after a little study of the code i still can't find the variable where the read sections are stored i thought it was %var% but i can not seem to use it...
My ideea was to use it in a textedit for example a path would be shown there and stored in ini.ini at settings/path but i don't understand enough the code you wrote to do this

#9 djeaton3162

djeaton3162
  • Members
  • 32 posts

Posted 21 September 2007 - 04:05 PM

What you guys are doing is way over my head...but I need it. :) I am setting some environment variables in a script, but need to read them from a ini file that others can edit and add to. The ini file would contain "set variable value" statements and I need to load them and set them in the program. Could one of you super-smart and really kind people dumb this down a bit for a newbie and tell me how I could use the above code to do something like this? I'm just not grasping how this code works or how to call the function when I don't know how many variables will be set in the INI file.
Daniel

#10 haichen

haichen
  • Members
  • 198 posts

Posted 21 September 2007 - 04:35 PM

have a look at VisualINI from Titan

#11 engunneer

engunneer
  • Fellows
  • 9162 posts

Posted 21 September 2007 - 04:38 PM

I've been meaning to posta again in this topic anyway. I have changed the function names so they can be put in my user library as INI.ahk

/*
INI_Init(inifile)     ;prepares the global variables to be populated
INI_Load(inifile)     ;Reads all the settings into the global variables from the file
INI_Save(inifile)     ;Saves all the settings from the global variables into the file

INI_ReadAll(inifile)  ;Synonym for INI_Load
INI_WriteAll(inifile) ;Synonym for INI_Save

*/
INI_Init(inifile = "inifile.ini"){
  global
  local key
  inisections:=0
 
  loop,read,%inifile%
  {
    if regexmatch(A_Loopreadline,"\[(\w+)]")
      {
        inisections+= 1
        section%inisections%:=regexreplace(A_loopreadline,"(\[)(\w+)(])","$2")
        section%inisections%_keys:=0
      }
    else if regexmatch(A_LoopReadLine,"(\w+)=(\w+)")
      {
        section%inisections%_keys+= 1
        key:=section%inisections%_keys
        section%inisections%_key%key%:=regexreplace(A_LoopReadLine,"(\w+)=(.*)","$1")
      }
  }
}

INI_readAll(inifile="inifile.ini"){
  INI_load(inifile)
}

INI_load(inifile="inifile.ini"){
  global
  local sec,var
  loop,%inisections%
    {
      sec:=A_index
      loop,% section%a_index%_keys
        {
          var:=section%sec% "_" section%sec%_key%A_index%
          iniread,%var%,%inifile%,% section%sec%,% section%sec%_key%A_index%
        }
    }
}

INI_writeAll(inifile="inifile.ini"){
  INI_Save(inifile)
}

INI_Save(inifile="inifile.ini"){
  global
  local sec,var
  loop,%inisections%
    {
      sec:=A_index
      loop,% section%a_index%_keys
        {
          var:=section%sec% "_" section%sec%_key%A_index%,var:=%var%
          iniwrite,%var%,%inifile%,% section%sec%,% section%sec%_key%A_index%
        }
    }
}


I also added two functions which are just aliases.

To use these functions, consider this example ini file.

inifile.ini
[Options]
font=Veranda
size=12

[users]
bsmith=Bob Smith
jdoe=Jane Doe

and now run this AHK file - the ini file will be created for you
inifile = inifile.ini

;first we make the example ini file for you - your script will not normally include this.
FileDelete, %inifile%
FileAppend,
(
[Options]
font=Veranda
size=12

[Users]
bsmith=Bob Smith
jdoe=Jane Doe
), %inifile%


;here is where we use our new user library functions.
INI_Init(inifile)
Listvars
Msgbox, First, we will look at the results of INI_Init.`n Close Listvars and Click OK when you have looked at the listvars window 

INI_Load(inifile)
Listvars
Msgbox, Now we look at the results of reading the ini file.`nNotice how the variables are made as Section_variable.`n Close Listvars and Click OK when you see this.

InputBox, myname, , Now we will add a new variable to the Users section - Enter your Name
;since we are making a new value in the ini file, we use INIWrite
IniWrite, %myname%, %inifile%, Users, %A_UserName%

;since we have changed the file, we should Init and read again.
INI_Init(inifile)
INI_Load(inifile)

Listvars
Msgbox, Now we have your username as an option.


Msgbox, Now we will loop through all users to say hello to you
;first we need to find out what section number is Users. We /could/ hardcode this, but that's no fun
;then we find out how many keys are in that section
Loop, %inisections%
  If (Section%A_index% = "Users")
  {
    UsersSection := A_index
    numberOfUsers := Section%A_index%_keys
  }

;now we can loop through each user
Loop, %numberOfUsers%
{
  This_username := Section%UsersSection%_key%A_index%
  This_realName := Users_%This_UserName%
  If (This_username = A_UserName)
    Msgbox, Hello, %This_Realname%
  else
    Msgbox, You are not %This_RealName% (%This_UserName%)
}

;if you only need to do something with your user, then you can do the much simpler
YourRealName := Users_%A_UserName%
Msgbox, Hello, %YourRealName%


;Now we will write a value to the ini file
Inputbox, Options_Font, , Type in the name of a font that you want to use `n(Any text is fine for this example)
Msgbox, the result (%Options_Font%) is now saved in Options_Font

INI_Save(inifile)
Msgbox, the ini file has been updated with your new text automatically.`n now imagine writing an INIWrite command for 50 or 60 different options.`nINI_Save takes care of them all for you.
Run, edit, %inifile%



If this is not helpful, I can share an application I made for work (minus a bit of stuff), so you can see how simple it is for basic ini usage.

#12 djeaton3162

djeaton3162
  • Members
  • 32 posts

Posted 21 September 2007 - 05:32 PM

Here is where I am confused. If your script of functions isn't inside my own script or "included", how does it find it? I love what you are doing with the sections as well. I have other things I want to add to the ini file later. :)
D.

#13 engunneer

engunneer
  • Fellows
  • 9162 posts

Posted 21 September 2007 - 05:37 PM

please read about the user library and the Standard Library. It let you "extend" the AHK language by Auto-including needed functions from %A_MyDocuments%\Autohotkey\Lib and from the Autohotkey library in Program Files.

#14 djeaton3162

djeaton3162
  • Members
  • 32 posts

Posted 21 September 2007 - 05:59 PM

please read about the user library and the Standard Library. It let you "extend" the AHK language by Auto-including needed functions from %A_MyDocuments%\Autohotkey\Lib and from the Autohotkey library in Program Files.

Thanks. The help file is good, but only if you know what to search on. This helps me a lot.
D.

#15 tic

tic
  • Members
  • 1902 posts

Posted 27 September 2007 - 02:13 PM

just a thought as ive seen this happen before in inis:

Loop, 2
{
	If A_Index = 1
	String := "[hello]"
	Else
	String := "                                [hello]"

	Regexmatch(String,"\[(\w+)]")
	yours := regexreplace(String,"(\[)(\w+)(])","$2")

	RegExMatch(String,"\[.*\]", MyMatch)
	StringMid, mine, MyMatch, 2, % StrLen(MyMatch)-2

	MsgBox, % "Your Match: " . yours . "`nMy Match: " . mine
}