IniRead() - Read some/all values from an ini file
Warning: code has been updated more recently than documentation. So stuff might not work as documented. See comments in code
Ini files are often used to store some general configuration settings for a program. The settings must be read from the ini file each time the program loads. Subsequently, however, the ini file is only accessed when a value is changed by the user. (This can be avoided by forcing manual editing of ini file values, e.g. with notepad.exe.)
IniRead() aims to take care of the initial loading of settings with a single function call. It does this by assuming that the structure of your ini file mirrors variables that store settings information within your script. For my scripts at least, this is usually the case.








IniRead(_IniFile="", _Options="")Usage: IniRead() reads an ini file and translates each key into an AutoHotkey variable initialized with the given value. Basically it is an alternate way to initialize variables at the top of your script.
You will probably be using IniRead() only once, inside your script's autorun section. The exception would be if there are multiple sections of the .ini file that you want to read at different times or under different conditionsCode:
IniRead("MyApp.ini", "sSettings") ; reads the [Settings] section from the ini file MyApp.ini into the script's memory.
The function returns the number of keys read, or a string containing each key read if the d option is used. This can be used to check if all the necessary values were read.Code:
DesiredKeys = Color`nHeight`nHotkey`nTimeout`nTitle`nWidth ; in alphabetical order
FoundKeys := IniRead("MyApp.ini", "sSettings d") ; using d option, which defaults to a newline (`n)
Sort, FoundKeys ; sorts the list of keys so the order they are found in the file won't matter
If (FoundKeys <> DesiredKeys) ; if the list of keys that were found does not match the list given then display an error
MsgBox, Some of the settings were missing!


Parameters:
I've changed the parameters but haven't updated this forum post. Look in the comments at the top of the code for more information.IniFile: The file to read. If this parameter is blank the function will use the first .ini file alphabetically in the working directory.Options: A space-delimited string in which you can indicate additional options, such as you see in the GUI command’s Options parameter. More info here: http://www.autohotkey.com/forum/topic77824.html.s - Section: Section to use out of whole file. Specify an asterisk (*) to only read the first section. Leave blank to read the entire filep - Prepend: Prepend this string to the variables. An asterisk (*) will be replaced by the current section named - Delimited List: Instead of returning the number of keys read, the function will return a string of all variables created (i.e. all keys read with any additional modifications made by _r or _p) delimited by the indicated characterr - Replace Bad Chars: One or more characters in key or section names that are unsuitable for AutoHotkey variable names will be replaced by this charactere - Error Behavior: Indicate/omit any combination of f/s/o/r to display an error dialog/exit silently if the ini file cannot be found/the desired section cannot be found/a preexisting variable will be overwritten/r will replace any inappropriate characters


Why use IniRead()There are many advantages to storing user settings in an ini file instead of inside the AutoHotkey code:- Values can be edited even if the script is compiled
- Tampering with the file cannot break AutoHotkey code
- An ini file is a familiar format for storing settings information
IniRead() merely aims to simplify the process of moving configuration settings into ini files. Normally this process requires the addition of many lines of AutoHotkey code; with IniRead() it should only take one short line.


Example:The below screenshot demonstrates the results of IniRead(). From right to left you can see the script that was executed, the contents of the ini file that script read, and the script's global variables after calling IniRead() as reported by ListVars. Notice the p option was used; otherwise duplicate variables would have been created.


Code:Code:
IniRead(_IniFile="", _Options="") ;http://www.autohotkey.com/forum/topic72442.html
{
Local _Reading, _Prepend, _Entries, _nSec, _nKey, _t := 0, _t1, _t2, _Literal := """", _Commands := "sa|ka|sl|sr|p|d|r|e"
;---------------------------------OPTIONS:-----------------------------------------------------------
; INITIAL DEFAULT NAME ABOUT
, _sa := "", _sa_def := "Sections*" ;sa = Section Array Creates the specified pseudoarray containing each section header that was read. An asterisk (*) will be replaced by the item number, otherwise it will be appended to the end. Item 0 will contain the size of the ray. Only applicable if all sections are being read (s = "")
, _ka := "", _ka_def := "Keys*" ;ka = Key Array Same as above but for individual keys. Similar to the d option
, _sl := "", _sl_def := "*" ;sl = Section (Literal) Section to use out of whole file. If multiple sections have the same name the first will be used. Specify an asterisk (*) to only read the first section. Leave blank to read the entire file
, _sr := "", _sr_def := "" ;sr = Section (RegEx) Same as above but will extract from all sections whose names match the given regular expression
, _p := "", _p_def := "*_" ;p = Prepend Prepend this string to the variables. An asterisk (*) will be replaced by the current section name
, _d := "", _d_def := "`n" ;d = Delimited List Instead of returning the number of keys read, the function will return a string of all variables created (i.e. all keys read with any additional modifications made by _r or _p) delimited by the indicated character(s)
, _r := "", _r_def := "_" ;r = Replace Bad Chars One or more characters in key or section names that are unsuitable for AutoHotkey variable names will be replaced by this character
, _e := "fso", _e_def := "" ;e = Error Behavior Indicate/omit any combination of f/s/o/r to display an error dialog/exit silently if the ini file cannot be found/the desired section cannot be found/a preexisting variable will be overwritten/r will replace any inappropriate characters
;----------------------------------------------------------------------------------------------------
While (_t := RegExMatch(_Options, "i)\s*\K(?P<1>" _Commands ")(?P<2>" _Literal "(?:[^" _Literal "]|" _Literal _Literal ")*" _Literal "(?= |$)|[^ ]*)", _t, _t + StrLen(_t1 _t2) + 1))
If (_t2 <> "") {
If (SubStr(_t2, 1, 1) = _Literal) and (StrLen(_t2) > 1) and (SubStr(_t2, 0, 1) = _Literal) and (_t2 := SubStr(_t2, 2, -1))
StringReplace, _t2, _t2, %_Literal%%_Literal%, %_Literal%, All
_%_t1% := _t2
} Else
_%_t1% := _%_t1%_def
If RegExMatch(_r, "[^\w#@$?]") or RegExMatch(_p, "[^\w*#@$?]") {
MsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, Neither the p nor r options may contain characters that are not alloewd in AutoHotkey variable names.
Return
}
_Entries := _d = "" ? 0 : _d
If !InStr(_p, "*")
_Prepend := _p
If (_IniFile = "") {
Loop, *.ini
{
_IniFile := A_LoopFileFullPath
Break
}
If (_IniFile = "") {
If InStr(_e, "f")
MsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, No .ini file found in working directory.
Return
}
} Else If !FileExist(_IniFile) {
If InStr(_e, "f")
MsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, File "%_IniFile%" not found or does not exist.
Return
}
If (_sl <> "") {
If (_sr <> "") {
MsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, Please enter either a sl (Section - Literal) or sr (Section - RegEx) value, not both.
Return
}
} Else If (_sr = "")
_Reading := True
If (_sa <> "") {
If RegExMatch(_sa, "[^\w#@$?*]")
_sa := RegExReplace(_sa, "[^\w#@$?*]")
If !InStr(_sa, "*")
_sa .= "*"
}
If (_ka <> "") {
If RegExMatch(_ka, "[^\w#@$?*]")
_ka := RegExReplace(_ka, "[^\w#@$?*]")
If !InStr(_ka, "*")
_ka .= "*"
If (_ka = _sa) {
MsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, The section output array (sa) and key output array (ka) cannot be the same.
Return
}
}
Loop, Read, %_IniFile%
{
_t = %A_LoopReadLine%
If (SubStr(_t, 1, 1) = "[") and (SubStr(_t, 0, 1) = "]") {
If (_sr <> "")
_Reading := RegExMatch(SubStr(_t, 2, -1), _sr) ? True : False
Else If (_sl <> "")
If _Reading
Break
Else If (SubStr(_t, 2, -1) = _sl) or (_sl = "*")
_Reading := True
If !_Reading
Continue
If InStr(_p, "*") {
StringReplace, _Prepend, _p, *, % RegExReplace(SubStr(_t, 2, -1), "[^\w#_t$?]+", _r, _t2), All
If _t2 and InStr(_e, "r") {
MsgBox, 262420, %A_ScriptName% - %A_ThisFunc%(): Error, A section name contained characters not allowed in AutoHotkey variable names. Replace these characters with "%_r%" ?
IfMsgBox NO
Return
}
}
If _sa {
_nSec += 1
StringReplace, _t1, _sa, *, %_nSec%, All
%_t1% := SubStr(_t, 2, -1)
}
} Else If _Reading and InStr(_t, "=") {
_t1 := RegExReplace(SubStr(_t, 1, InStr(_t, "=") - 1), "[^\w#_t$?]+", _r, _t2)
If _t2 and InStr(_e, "r") {
MsgBox, 262420, %A_ScriptName% - %A_ThisFunc%(): Error, A key name contained characters not allowed in AutoHotkey variable names. Replace these characters with "%_r%" ?
IfMsgBox NO
Return
}
If (%_Prepend%%_t1% <> "") and InStr(_e, "o") {
MsgBox, 262420, %A_ScriptName% - %A_ThisFunc%(): Error, The variable "%_Prepend%%_t1%" has already been assigned either by IniRead() or elsewhere in the script. Overwrite it with the value from the .ini file?`nTo avoid this error you can try using the p or s options
IfMsgBox NO
Return
}
%_Prepend%%_t1% := SubStr(_t, InStr(_t, "=") + 1)
If (_d <> "") {
StringReplace, _Entries, _Entries, %_d%%_Prepend%%_t1%%_d%, %_d%, All
_Entries .= _Prepend _t1 _d
} Else
_Entries += 1
If _ka {
_nKey += 1
StringReplace, _t, _ka, *, %_nKey%, All
%_t% := _Prepend _t1
}
}
}
If (_sl <> "") and !_Reading and InStr(_e, "s")
MsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, Section "%_sl%" was not found in ini file "%_IniFile%", therefore no variables were assigned.
If _sa {
StringReplace, _t, _sa, *, 0, All
%_t% := _nSec
}
If _ka {
StringReplace, _t, _ka, *, 0, All
%_t% := _nKey
}
Return _d = "" ? _Entries : SubStr(_Entries, 2, -1)
}
~ Created with Quick Functions for Forums by berban ~