How to access INI Files in C# .NET

Sometimes you’ll find your self in a situation where you need to use outdated techniques in order to support outdated applications … That time you’ll recognize that .NET does not support INI Files anymore.

So let us take a time machine and write our own INI File access.

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

[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);


[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);

Now let us code a small example that reads a simple ini file.

/*
* Try to read the content of a simle INI file
*/
List<string> categories = GetCategories(iniFile);
foreach (string category in categories)
{
    Console.WriteLine(category);
    
    /*
     * Get the keys
     */
    List<string> keys = GetKeys(iniFile, category);
    foreach (string key in keys)
    {
        /*
         * Now output the content
         */
        string content = GetIniFileString(iniFile, category, key, defaultValue);
        Console.WriteLine(string.Concat(" ", key, "\t", content));
    }
}

As you can see I used three new methods GetCategories, GetKeys and GetIniFileString. These new methods are not an integrated part of the .NET framework. So we have to implement them by our own.

The following method reads a list with all categories the Ini File contains. A category within the Ini File is tagged with brackets, like [ODBC] or [GLOBALS]. The API GetPriveProfileString fills an internal buffer separated by \ 0. In order to get a generic list we have to split that buffer with the token \ 0. The last 2 values can be cutted, because they are always empty.

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

Using the same technique we can read the keys from a category.

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

Lat but not least we need to read the value of the key we found.

private static string GetIniFileString(string iniFile, string category, string key, string defaultValue)
{
    string returnString = new string(' ', 1024);
    GetPrivateProfileString(category, key, defaultValue, returnString, 1024, iniFile);
    return returnString.Split('\ 0')[0];
}

That’s all – and uhh, before I forget. Here’s an example for writing values to an INI File. We can use the declared and imported API method itself, without writing a wrapper to use it.

WritePrivateProfileString("GLOBAL", "Stuff", "The content of that stuff", "MyIniFile.ini");

But be aware, if you do not specify a directory, the INI File resides always within the Windows Directory. Most times this will be C:\Windows\

So have a nice day
Cheers

Gerhard

You can download the example using the following link: How to access INI Files in C# .NET

About these ads

16 Responses to “How to access INI Files in C# .NET”

  1. Shaun Says:

    Is there a way to make your application work in .NET Framework 1.1. “List” declaration seems to be supported in with Generics namespace in .NET Framework 2.0, is that true? How can I make this code run in the 1.1 environment.
    Thanks in advance!

  2. Gerhard Stephan Says:

    NET Framework 1.1 does not know generics. That’s why you have to replace List with ArrayList. That should be all.

    Cheers
    Gerhard

  3. Best practice of storing configuration in INI Files with C# .NET « All about nothing Says:

    […] Because of the high resonance about the article “How to access INI Files in C# .NET” I want to introduce a blog entry on how to store configuration data into INI Files. […]

  4. Ashish Says:

    I have a scenario where I have to write 2-3 keys but with different values in the same section.
    How to write duplicate keys in the same section?

    Thanks in Advance

  5. Gerhard Stephan Says:

    Hi Ashish,

    Duplicate keys are not valid within an INI File. You have to enumerate the keys and add a counter to it. E.g.

    Param01 = xxx
    Param02 = yyy

    Cheers
    Gerhard

  6. Ralph Says:

    NET Framework 1.1 does not know generics. That’s why you have to replace List with ArrayList. That should be all.

    It seems it’s not. Every time I run this example I only get the first element, it’s just like I cannot get beyond the first ”. I tried everything it came to my mind, but I cannot retrieve the rest, any suggestion?

  7. Nathan Says:

    For those who are still wondering why the only character taken by the GetKeys/GetCategories functions is ” : I don’t really know if this problem occurs using .Net 2.0 (I’m currently using .Net 1.0 framework) but a string cannot be used as an argument of GetPrivateProfileString (argument “lpReturnString”, the string to fill). Instead, you should use StringBuilder to get a single string but it will truncate the StringBuilder at the first null it finds. In order to get the list of keys, you can use a char[] and then pass this char[] to the constructor of a new string. Then, it’s the same way of using it (split it into a list of strings, etc …).

    Here is an example :

    Dllimport :
    [DllImport(“kernel32″)]
    private static extern int GetPrivateProfileString(string section, string key, string defaultValue, [In, Out] char[] actualValue, int size, string ini_path);

    GetKeys method :
    private static ArrayList GetKeys(string iniFile, string category)
    {
    string test = new string(‘ ‘, 65535);
    char[] returnString = test.ToCharArray();
    GetPrivateProfileString(category, null, null, returnString, 65536, iniFile);
    string resultString = new string(returnString);
    ArrayList result = new ArrayList(resultString.Split(”));
    result.RemoveRange(result.Count-2,2);
    return result;
    }

    (Actually I couldn’t make an implicit conversion of a string to a char[]… http://msdn2.microsoft.com/fr-fr/library/x9h8tsay(VS.80).aspx said that it’s possible though :/ )

  8. Naresh Says:

    Thank you very much for u r great help in creating .ini file.
    i helped me alot in my project. Thank you very much. Especially entire class is very useful

  9. Rogelio Says:

    I have a question about writing to the ini. what happens if the node does not exist? will it just create it?

    does writing a key update/create ?

    or just update?

  10. Gerhard Says:

    Hi Rogelio,

    the key will be created. Even the complete file will be created, if it does not exists.

    – Gerhard

  11. ian Says:

    Thanks for this, very useful indeed. So much so that I’m going to blog about it myself and of course credit your post.

  12. Accessing INI Files in C# » iandevlin.com Says:

    […] 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 […]

  13. keith Says:

    Hi, there is an Ini Parser available in CommonLibrary.NET that works pretty well. The API is also overloaded to get default values ( that you supply ) if the key isn’t there.

    http://commonlibrarynet.codeplex.com/.

  14. Dick Williams Says:

    I’m writing an app that writes to the .ini file for a second app and then immediately starts that second app. How can I be sure the last changes I made to the second app’s .ini file are in the version of the .ini file the second app reads as opposed to being cashed somewhere?


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 106 other followers

%d bloggers like this: