BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Input / Output
.NET 1.1+

Reading and Writing INI Files

Initialisation files known as INI files provide a standard means for storing configuration information for software in a text file. Although rarely used by .NET applications, there are situations where these files must be read and written to using C#.

INI Files

Older versions of Microsoft Windows used INI files to store configuration information for the operating system and its applications. These are simple text files that can be edited using software such as Notepad. They hold a series of key / value pairs organised into categories where all of the category names, key names and values are held as strings.

The following shows a sample of the contents of an INI file. The two section names, "Colours" and "Font" are delimited with brackets. The key / value pairs for a section appear below the section name. For example, the Colours section contains a key of "Foreground" with an associated value of "White".

[Colours]
Background=Black
Foreground=White
[Font]
Face=Arial
Size=12pt

Usually, when you create applications using C# and the .NET framework, you will not use INI files. It is more common to store settings in an XML-based configuration file or in the registry. However, if your software shares settings with a legacy application it may be easier to use its configuration file, rather than duplicating the information elsewhere.

The .NET framework does not support the use of INI files directly. However, you can use Windows API functions with Platform Invocation Services (P/Invoke) to write to and read from the files. In this article we will create a class that represents INI files and uses Windows API functions to manipulate them.

Windows API Functions

There are two Windows API functions that we will use to work with INI files. These are named WritePrivateProfileString and ReadPrivateProfileString.

WritePrivateProfileString

WritePrivateProfileString is used to store new and updated settings in an INI file. The signature of the function is:

bool WritePrivateProfileString(
    string lpAppName, string lpKeyName, string lpString, string lpFileName);

The function returns a Boolean value that is true if the write is successful and false if it fails. The parameters are as follows:

  • lpAppName. Specifies the name of the section that is to be written to.
  • lpKeyName. Specifies the name of the key that is to be set.
  • lpString. Specifies the value for the key.
  • lpFileName. Specifies the path and name of the INI file to be updated. If the file does not exist, it is created.

ReadPrivateProfileString

ReadPrivateProfileString is used to read data from an INI file. Depending upon its use, the function reads single values, all key names from a section or all section names:

uint GetPrivateProfileString(
    string lpAppName, string lpKeyName, string lpDefault, string lpReturnedString,
    uint nSize, string lpFileName);

The function returns an unsigned integer that contains the number of characters in the returned value. The parameters are as follows:

  • lpAppName. Specifies the name of the section that is to be read. This can be set to null to return all of the section names.
  • lpKeyName. Specifies the name of the key that is to be read. If set to null when lpAppName is not null, the returned value will contain the names of the keys in the specified section.
  • lpDefault. Specifies a default value to return if the key is not present.
  • lpReturnedString. This parameter is provided with a string that acts as a buffer. The result of the operation is written into the buffer, changing the value of the string.
  • nSize. Specifies the maximum size of the string that will be returned in lpReturnedString. This should be equal to the size of the buffer. The value read from the INI file will be truncated if it is longer than nSize.
  • lpFileName. Specifies the path and name of the INI file to be read. This file must exist.

NativeMethods Class

Now that we've seen the signatures of the Windows API functions that we'll be using, let's create a class to hold them. Create a new class named, "NativeMethods" and add the following using directive to give easy access to the P/Invoke attributes.

using System.Runtime.InteropServices;

The code for the class is as follows. Note that no access modifier has been included for the class itself so it will have an internal scope. This will allow the IniFile class to use the API functions without exposing them publicly.

class NativeMethods
{
    [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    internal static extern bool WritePrivateProfileString(
        string lpAppName, string lpKeyName, string lpString, string lpFileName);

    [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    internal static extern uint GetPrivateProfileString(
        string lpAppName, string lpKeyName, string lpDefault, string lpReturnedString,
        uint nSize, string lpFileName);
}
8 December 2011