When developing a desktop application, there will be times when you want to store settings for your program. A database is one option, but on Windows, you might just wish to have your settings stored in an INI file. One way to work with an INI file in C# is with the Nini Library. This makes it quite easy to read from and write to an INI file.
Let’s get started.
After installing the library, we’ll need to set our namespace.
1
|
using
Nini
.
Config
;
|
What will our INI file look like? Something like this:
1
2
3
4
|
;
conf
.
ini
[
Options
]
Zipped
=
0
Filename
=
test
.
txt
|
For my application, I decided to make a class devoted to the configuration file. So, let’s define that and a few other variables.
1
2
3
4
5
6
7
8
|
public
class
OurConfig
{
string
NL
=
Environment
.
NewLine
;
// New line character
private
string
configFile
=
"conf.ini"
;
// Our INI file
IConfigSource
config
;
// Instance of our config
}
|
Now that we have our variables declared, let’s create a couple of useful methods.
1
2
3
4
5
6
7
8
9
|
public
void
set_is_zip
(
int
zipped
)
{
config
.
Configs
[
"Options"
]
.
Set
(
"Zipped"
,
zipped
)
;
}
public
void
set_filename
(
string
fname
)
{
config
.
Configs
[
"Options"
]
.
Set
(
"Filename"
,
fname
)
;
}
|
These two methods will update the INI file with new settings, should we change them in our program. Of course, if we make these changes, they need to be saved. Thankfully, we can declare something in our constructor (which we will write a little later) that will auto-save our changes as we make them.
1
|
config
.
AutoSave
=
true
;
|
Now, let’s create a pair of methods to return the data. This will be useful in our program when we need to use these settings.
1
2
3
4
5
6
7
8
9
|
public
int
return_is_zip
(
)
{
return
config
.
Configs
[
"Options"
]
.
Get
(
"Zipped"
)
;
}
public
string
return_filename
(
)
{
return
config
.
Configs
[
"Options"
]
.
Get
(
"Filename"
)
;
}
|
With these methods, we now have a basic class for handling a configuration file. All that is left is our constructor.
But before we get to the constructor, there is something else I created. What if our INI file doesn’t exist? I decided that I would make a function to create a default INI file, should the old one not exist anymore. This is also useful if we want to distribute our program without an INI file.
1
2
3
4
5
6
7
8
9
10
11
|
private
void
fill_new_ini
(
)
{
// Put default values into the INI file
// Essentially, we're writing a blank file, so this is fairly simple
string
toWrite
=
";conf.ini"
+
NL
+
"[Options]"
+
NL
+
"Zipped = 0"
+
NL
+
"Filename = test.txt"
+
NL
;
System
.
IO
.
File
.
WriteAllText
(
@
"conf.ini"
,
toWrite
)
;
}
|
We can do a check when we initialize our class that will check to see whether or not this file exists. If not, we’ll create it so we can work with it.
That makes this our constructor:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public
OurConfig
(
)
{
// Initialize the INI file if it doesn't exist
try
{
configFile
=
new
IniConfigSource
(
"conf.ini"
)
;
}
catch
(
Exception
ex
)
{
// Write default values into it
fill_new_ini
(
)
;
configFile
=
new
IniConfigSource
(
"conf.ini"
)
;
}
configFile
.
AutoSave
=
true
;
// Auto save config file as we make changes
}
|
Our whole class thus looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
using
Nini
.
Config
;
public
class
OurConfig
{
string
NL
=
Environment
.
NewLine
;
// New line character
private
string
configFile
=
"conf.ini"
;
// Our INI file
IConfigSource
config
;
// Instance of our config
public
OurConfig
(
)
{
// Initialize the INI file if it doesn't exist
try
{
configFile
=
new
IniConfigSource
(
"conf.ini"
)
;
}
catch
(
Exception
ex
)
{
// Write default values into it
fill_new_ini
(
)
;
configFile
=
new
IniConfigSource
(
"conf.ini"
)
;
}
configFile
.
AutoSave
=
true
;
// Auto save config file as we make changes
}
private
void
fill_new_ini
(
)
{
// Put default values into the INI file
// Essentially, we're writing a blank file, so this is fairly simple
string
toWrite
=
";conf.ini"
+
NL
+
"[Options]"
+
NL
+
"Zipped = 0"
+
CL
+
"Filename = test.txt"
+
CL
;
System
.
IO
.
File
.
WriteAllText
(
@
"conf.ini"
,
toWrite
)
;
}
public
void
set_is_zip
(
int
zipped
)
{
config
.
Configs
[
"Options"
]
.
Set
(
"Zipped"
,
zipped
)
;
}
public
void
set_filename
(
string
fname
)
{
config
.
Configs
[
"Options"
]
.
Set
(
"Filename"
,
fname
)
;
}
public
int
return_is_zip
(
)
{
return
config
.
Configs
[
"Options"
]
.
Get
(
"Zipped"
)
;
}
public
string
return_filename
(
)
{
return
config
.
Configs
[
"Options"
]
.
Get
(
"Filename"
)
;
}
}
// End OurConfig
|
That’s how simple it can be to work with your own INI files in C#.
Did you find this useful? Let me know in the comments!
xml
Nini has it's own XML configuration file structure. It provides more flexibility than does the .NET configuration file format. It's main advantages are that you can have more than one XML configuration file and that the format is much more concise. Here is an example of the format. You will notice that it resembles an INI file quite closely. The configuration values are the same as the INI in the previous examples:
<!-- MyApp.xml --> <Nini> <Section Name="Logging"> <Key Name="File Name" Value="MyApp.log" /> <Key Name="MessageColumns" Value="5" /> <Key Name="MaxFileSize" Value="40000000000000" /> </Section> </Nini>
To load the file is very simple:
// Loads the XML file XmlConfigSource source = new XmlConfigSource("MyApp.xml"); // Retrieves a value long maxFileSize = source.Configs["Logging"].GetLong("MaxFileSize");