Click here to Skip to main content
Click here to Skip to main content

Application Settings the .NET way. INI, Registry, or XML

, 27 Oct 2004 BSD
Rate this:
Please Sign up or sign in to vote.
In this article, I’ll explain how you can easily store and retrieve your application settings with just a few lines of code

Introduction

INI files and the registry are generally things of the past for .NET applications. But what to use? XML seems appropriate, but one look at System.XML is enough to scare most developers off, especially just to store a few fields. Fortunately, there is a very easy way in .NET to solve this, but one that is usually not seen by developers. In this article, I’ll explain how you can easily store and retrieve your application settings with just a few lines of code.

History

In Windows 3.1, developers used INI files to store settings. In general, they worked pretty well for simple settings, but were not appropriate for more complex data. INI files also did not account for multiple users, and thus Microsoft invented the registry.

Along came the registry with Win32. The registry was fast, hierarchical, multi user, and allowed storage of typed data. But unfortunately, the registry was a central system component and was not contained as part of the application install.

Next, XML became popular. XML offers fast, hierarchical storage of typed data. However, XML is so flexible that for most users doing anything simple is quite an undertaking. Fortunately, there are easier ways than using System.XML and handling everything yourself.

Old Ways

Many users have simply resorted to using INI files or the registry. INI files are not supported in .NET. To use INI files, a developer must call the Win32 API directly, or use some prepared classes on the Internet that use the Win32 API. For the registry, classes are available in Microsoft.Win32. XML however is portable and can be easily edited by end users if necessary.

How

The secret to painless XML settings files is to use a typed DataSet. A typed DataSet is actually an in memory dataset for working with ADO.NET, but they have many other uses as well. To add a typed DataSet to your application, right click on the project in the Solution Explorer, and select Add New Item. Now select DataSet, and give the dataset a name.

Now, we have a blank DataSet in our project. For the purposes of a demo, I have created a main form already that looks like this.

I have chosen these for the demo as they give us three types of data to store, a string, an integer, and a Boolean. Now, let’s design our DataSet around these.

Open the Solution Explorer and find the newly created DataSet.

When you double click on Settings.xsd, you will see a designer like this:

This is a blank DataSet. A DataSet can contain several tables, but for this demo, we will add just one. Open the toolbox, and you will see different items than you normally see in a WinForms or a WebForms application.

There are a lot of items in the toolbox related to DataSets, but for the needs of this article, we only need Element. Double click on Element to add one to the DataSet. The DataSet should now look like this:

The Element type corresponds to a DataTable. Let’s name it Main (change the highlighted text above to Main). Now, let’s enter the fields that we want to store. The element should look like this when finished:

Visual Studio will now take this DataSet and make a set of classes for us that we can use. So now, let’s take a look at the Load and Save buttons on the main form. These events make use of ConfigPathname, this is a field that is predefined in the demo. ConfigPathname just holds the path and filename of the settings file.

C#

private void butnSave_Click(object sender, System.EventArgs e) {
    Settings xDS = new Settings();
    Settings.MainRow xRow = xDS.Main.NewMainRow();
    xRow.Username = textUsername.Text.Trim();
    xRow.PIN = int.Parse(textPIN.Text.Trim());
    xRow.Admin = chckAdmin.Checked;
    xDS.Main.AddMainRow(xRow);
    xDS.WriteXml(ConfigPathname, System.Data.XmlWriteMode.IgnoreSchema);
}

private void butnLoad_Click(object sender, System.EventArgs e) {
    if (new FileInfo(ConfigPathname).Exists) {
        Settings xDS = new Settings();
        xDS.ReadXml(ConfigPathname, System.Data.XmlReadMode.IgnoreSchema);
        if (xDS.Main.Rows.Count > 0) {
            Settings.MainRow xRow = xDS.Main[0];
            if (!xRow.IsUsernameNull()) {
                textUsername.Text = xRow.Username;
            }
            if (!xRow.IsPINNull()) {
                textPIN.Text = xRow.PIN.ToString();
            }
            if (!xRow.IsAdminNull()) {
                chckAdmin.Checked = xRow.Admin;
            }
        }
    }
}

Visual Basic.NET

Private Sub butnSave_Click(ByVal sender As System.Object, 
ByVal e As System.EventArgs) Handles butnSave.Click
  Dim xDS As New Settings
  Dim xRow As Settings.MainRow
  xRow = xDS.Main.NewMainRow
  xRow.Username = textUsername.Text.Trim()
  xRow.PIN = Int32.Parse(textPIN.Text.Trim())
  xRow.Admin = chckAdmin.Checked
  xDS.Main.AddMainRow(xRow)
  xDS.WriteXml(ConfigPathname, System.Data.XmlWriteMode.IgnoreSchema)
End Sub

Private Sub butnLoad_Click(ByVal sender As System.Object, 
ByVal e As System.EventArgs) Handles butnLoad.Click
  If New FileInfo(ConfigPathname).Exists Then
    Dim xDS As New Settings
    Dim xRow As Settings.MainRow
    xDS.ReadXml(ConfigPathname, System.Data.XmlReadMode.IgnoreSchema)
    If xDS.Main.Rows.Count > 0 Then
      xRow = xDS.Main.Rows.Item(0)
      If Not xRow.IsUsernameNull() Then
        textUsername.Text = xRow.Username
      End If
      If Not xRow.IsPINNull() Then
        textPIN.Text = xRow.PIN.ToString()
      End If
      If Not xRow.IsAdminNull() Then
        chckAdmin.Checked = xRow.Admin
      End If
    End If
  End If
End Sub

When loading the DataSet back, it is necessary to check each field for null. In our demo, they would never be null, but if you later add fields and your application tries to load a file that was saved with an older version, fields could be null. End users might also directly edit your settings files. Accessing a field while it is null will generate an exception.

If you run the demo, you can enter some test values and then click Save.

After clicking Save, the demo will create a .settings file in the same directory as the .exe. Normally, this is bin/debug/SettingsDemo.exe.Settings. If you open this file, you will see it is a standard XML file and can easily be edited.

<?xml version="1.0" standalone="yes"?>
<Settings xmlns="http://tempuri.org/Settings.xsd">
  <Main>
    <Username>Kudzu</Username>
    <PIN>1234</PIN>
    <Admin>true</Admin>
  </Main>
</Settings>

Now, if you run the application again, you can click the Load button to load these settings.

In this demo, we only stored one row in the DataTable. But DataTables can contain multiple rows, and a DataSet can even contain multiple related or unrelated DataTables.

Conclusion

XML files are a widespread standard that allows easy storage of structured typed data. Use of XML files allows easy editing by end users, and even by other software. Using typed DataSets, you can easily store your settings in XML files.

License

This article, along with any associated source code and files, is licensed under The BSD License

Share

About the Author

Chad Z. Hower, a.k.a. Kudzu
"Programming is an art form that fights back"
www.KudzuWorld.com
 
Formerly the Regional Developer Adviser (DPE) for Microsoft Middle East and Africa, he was responsible for 85 countries spanning 4 continents and 10 time zones. Now Chad is a Microsoft MVP.
 
Chad is the chair of several popular open source projects including Indy and Cosmos (C# Open Source Managed Operating System).
 
Chad is the author of the book Indy in Depth and has contributed to several other books on network communications and general programming.
 
Chad has lived in Canada, Cyprus, Switzerland, France, Jordan, Russia, Turkey, and the United States. Chad has visited more than 60 countries, visiting most of them several times.

Comments and Discussions

 
QuestionAnybody modify this to do it in a loop? PinmemberKraig_mn20-Sep-13 4:51 
AnswerRe: Anybody modify this to do it in a loop? PinmemberChad Z. Hower aka Kudzu20-Sep-13 4:53 
GeneralRe: Anybody modify this to do it in a loop? PinmemberKraig_mn20-Sep-13 4:58 
GeneralRe: Anybody modify this to do it in a loop? PinmemberChad Z. Hower aka Kudzu20-Sep-13 11:11 
GeneralRe: Anybody modify this to do it in a loop? PinmemberKraig_mn23-Sep-13 5:07 
GeneralRe: Anybody modify this to do it in a loop? PinmemberKraig_mn23-Sep-13 5:54 
GeneralDataSet.ReadXml has arror PinmemberMakso13-Aug-09 22:18 
GeneralRe: DataSet.ReadXml has arror PinmemberChad Z. Hower aka Kudzu14-Aug-09 3:46 
GeneralRe: DataSet.ReadXml has arror PinmemberMakso17-Aug-09 23:56 
GeneralRe: DataSet.ReadXml has arror PinmemberChad Z. Hower aka Kudzu18-Aug-09 15:37 
Generalgood article PinmemberDonsw8-May-09 16:24 
GeneralTrue but.... PinmemberAhsanS9-Nov-08 17:33 
GeneralRe: True but.... PinmemberChad Z. Hower aka Kudzu18-Nov-08 15:15 
QuestionHow to secure these settings? Pinmembervinay_kawade14-Jul-08 13:12 
AnswerRe: How to secure these settings? PinmemberChad Z. Hower aka Kudzu14-Jul-08 13:31 
QuestionAdd a field later? PinmemberStephenKearney15-Sep-07 10:11 
AnswerRe: Add a field later? PinmemberChad Z. Hower aka Kudzu8-Oct-07 7:36 
Generali know you from somewhere... Pinmemberferdna8-Sep-07 9:56 
GeneralRe: i know you from somewhere... PinmemberChad Z. Hower aka Kudzu2-Feb-08 0:16 
GeneralMultiple Dtata tables Pinmembersid_boss16-Mar-07 2:10 
GeneralRe: Multiple Dtata tables PinmemberChad Z. Hower aka Kudzu2-Feb-08 0:17 
GeneralDarn It PinmemberSteveWaNet24-Nov-06 17:42 
GeneralRe: Darn It PinmemberSteveWaNet25-Nov-06 7:27 
GeneralRe: Darn It (No Element is VS 2008 Team Suite) [modified] PinmemberMichael90003-Dec-09 16:10 
GeneralButton backcolor PinmemberThe Mighty Atom1-Sep-06 7:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.141022.2 | Last Updated 28 Oct 2004
Article Copyright 2004 by Chad Z. Hower aka Kudzu
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid