Accessing INI Files in C#

Recently I had the need to access and read in data from the old school style ini file. I was struggling to find the best way to go about doing this, until I came across this blog post by Gerhard Stephan. In it, he describes how to attach to the Windows KERNEL32.dll file and use the Windows functions GetPrivateProfileString and WritePrivateProfileString to read from and write to Windows ini files.

Using KERNEL32.DLL

First of all, two functions need to be declared in order to be able to use the functions within Window’s KERNEL32.dll.

First of all you have to declare two methods which are necessary to access an INI File.

To read data from the ini file we need:

[DllImport("KERNEL32.DLL", EntryPoint = "GetPrivateProfileStringW",
   SetLastError=true, CharSet=CharSet.Unicode, ExactSpelling=true,
   CallingConvention=CallingConvention.StdCall)]
   private static extern int GetPrivateProfileString(
      string lpAppName,
      string lpKeyName,
      string lpDefault,
      string lpReturnString,
      int nSize,
      string lpFilename);

And to write data to the ini file we need:

[DllImport("KERNEL32.DLL", EntryPoint="WritePrivateProfileStringW",
   SetLastError=true, CharSet=CharSet.Unicode, ExactSpelling=true,
   CallingConvention=CallingConvention.StdCall)]
   private static extern int WritePrivateProfileString(
      string lpAppName,
      string lpKeyName,
      string lpString,
      string lpFilename);

Retrieving data

Then 3 more functions need to be defined to use the functions above. Within an ini file, _categories_are those items that are contained within square brackets, e.g. [MODULE], keys are the items that are within categories to the left of the equal sign, e.g. ThisFlag=True, and values are the values of keys to the right of the equal sign.

To retrieve the categories from the ini file, we define GetCategories as follows:

private static List<string> GetCategories(string iniFile) {
&nbsp;&nbsp;&nbsp;&nbsp;string returnString = new string(&#039; &#039;, 65536);
&nbsp;&nbsp;&nbsp;&nbsp;GetPrivateProfileString(null, null, null, returnString, 65536,
&nbsp;&nbsp;&nbsp;&nbsp;iniFile);
&nbsp;&nbsp;&nbsp;&nbsp;List<string> result = new List<string>(returnString.Split(&#039;\0&#039;));
&nbsp;&nbsp;&nbsp;&nbsp;result.RemoveRange(result.Count - 2, 2);
&nbsp;&nbsp;&nbsp;&nbsp;return result;
}

The keys can then be retrieved from each category using:

private static List<string>; GetKeys(string iniFile, string category) {
&nbsp;&nbsp;&nbsp;&nbsp;string returnString = new string(&#039; &#039;, 32768);
&nbsp;&nbsp;&nbsp;&nbsp;GetPrivateProfileString(category, null, null, returnString, 32768,
&nbsp;&nbsp;&nbsp;&nbsp;iniFile);
&nbsp;&nbsp;&nbsp;&nbsp;List<string> result = new List<string>(returnString.Split(&#039;\0&#039;));
&nbsp;&nbsp;&nbsp;&nbsp;result.RemoveRange(result.Count-2,2);
&nbsp;&nbsp;&nbsp;&nbsp;return result;
}

(Note that in each of the two above cases, the last 2 entries are removed as they are always empty)

A value for a specific key can then be retrieved using GetValue:

private static string GetValue(string iniFile, string category,
&nbsp;&nbsp;&nbsp;&nbsp;string key, string defaultValue) {
&nbsp;&nbsp;&nbsp;&nbsp;string returnString = new string(&#039; &#039;, 1024);
&nbsp;&nbsp;&nbsp;&nbsp;GetPrivateProfileString(category, key, defaultValue, returnString,
&nbsp;&nbsp;&nbsp;&nbsp;1024, iniFile);
&nbsp;&nbsp;&nbsp;&nbsp;return returnString.Split(&#039;\0&#039;)[0];
}

Here’s a code sample to illustrate how to actually use the above functions to retrieve the ini file data. This code will read and print to screen all the data within the ini file located at fullPathToIniFile.

List<string> categories = GetCategories(fullPathToIniFile);
foreach (string category in categories) {
&nbsp;&nbsp; Console.WriteLine(category);
&nbsp;&nbsp; List<string> keys = GetKeys(fullPathToIniFile, category);
&nbsp;&nbsp; foreach (string key in keys) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string value = GetValue(fullPathToIniFile, category, key, "");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(key + " : " + value);
&nbsp;&nbsp; }
}

Writing to an ini file

Writing to an ini file is much simpler and doesn’t require any wrapper classes like above. To write to an ini file, simply call the following:

WritePrivateProfileString("CATEGORY", "KeyName", "The value of KeyName", "MyIniFile.ini");

If you don’t specify a directory, it will default to C:\Windows.

I hope this has been of some use to you, it certainly was to me and I have Gerhard Stephan to thank.