端くれプログラマの備忘録 C# [C#] INIファイルを読み書きする

[C#] INIファイルを読み書きする

Windowsにはアプリの設定を保存する方法がいくつかある。古い順に挙げるとINIファイル、レジストリ、XMLファイルなど。中でもINIファイルは、取り扱いが楽なのでいまだに使われている現場もある。エディタで開いて自由に設定を変更できるし、アンインストール時にレジストリにゴミを残す心配も無い。

C#でINIファイルを読み書きするには、WindowsのDLLをインポートすることで、Windows APIとして提供されているINIファイルのアクセス関数を使うのが手っ取り早い。

参考までに自作クラスを紹介しておく。

// WIN32 API wrapper
class IniFileUtils
{
    [DllImport("KERNEL32.DLL")]
    public static extern uint GetPrivateProfileString(
        string lpAppName, string lpKeyName, string lpDefault,
        StringBuilder lpReturnedString, uint nSize, string lpFileName);

    [DllImport("KERNEL32.DLL", EntryPoint="GetPrivateProfileStringA")]
    public static extern uint GetPrivateProfileStringByByteArray(
        string lpAppName, string lpKeyName, string lpDefault,
        byte[] lpReturnedString, uint nSize, string lpFileName);

    [DllImport("KERNEL32.DLL")]
    public static extern uint GetPrivateProfileInt(
        string lpAppName, string lpKeyName, int nDefault, string lpFileName);

    [DllImport("KERNEL32.DLL")]
    public static extern bool WritePrivateProfileString(
        string lpAppName, string lpKeyName, string lpString, string lpFileName);

    // Self-Testing
    [Conditional("DEBUG")]
    public static void Test()
    {
        string fileName = @"C:\Temp\Test.ini";

        // Write strings.
        bool result;
        result = WritePrivateProfileString("App1", "Key1", "Hello", fileName);
        Debug.Assert(result);
        result = WritePrivateProfileString("App1", "Key2", "12345", fileName);
        Debug.Assert(result);
        result = WritePrivateProfileString("App2", "Key1", "World", fileName);
        Debug.Assert(result);

        // Read string.
        StringBuilder sb = new StringBuilder(32);
        GetPrivateProfileString("App1", "Key1", "Default", sb, (uint)sb.Capacity, fileName);
        Trace.WriteLine("[App1] Key1 = " + sb.ToString());
         // Read integer.
        uint value = GetPrivateProfileInt("App1", "Key2", 0, fileName);
        Trace.WriteLine("[App1] Key2 = " + value);
         // List up keys.
        byte[] buf1 = new byte[1024];
        uint size1 = GetPrivateProfileStringByByteArray("App1", null, "", buf1, (uint)buf1.Length, fileName);
        string str1 = Encoding.Default.GetString(buf1, 0, (int)size1 - 1);
        string[] keys = str1.Split('\0');
        foreach (string key in keys)
        {
            Trace.WriteLine("[App1] Key = " + key);
        }

        // List up sections.
        byte[] buf2 = new byte[1024];
        uint size2 = GetPrivateProfileStringByByteArray(null, null, "", buf2, (uint)buf2.Length, fileName);
        string str2 = Encoding.Default.GetString(buf2, 0, (int)size2 - 1);
        string[] sections = str2.Split('\0');
        foreach (string section in sections)
        {
            Trace.WriteLine("Section = " + section);
        }

        Debug.Assert(sb.ToString() == "Hello");
        Debug.Assert(value == 12345);

        Debug.Assert(keys.Length == 2);
        Debug.Assert(Array.IndexOf(keys, "Key1") >= 0);
        Debug.Assert(Array.IndexOf(keys, "Key2") >= 0);

        Debug.Assert(sections.Length == 2);
        Debug.Assert(Array.IndexOf(sections, "App1") >= 0);
        Debug.Assert(Array.IndexOf(sections, "App2") >= 0);
    }
}