最近、C#でiniファイルのセクションを全て取得する必要があったので、その方法についてメモしておく。
iniファイルは
[Bob]
Age=17
[John]
Age=6
[Mike]
Age=31
[Ken]
Age=35
[Alice]
Age=4
Age=17
[John]
Age=6
[Mike]
Age=31
[Ken]
Age=35
[Alice]
Age=4
のような構造になっている。[]で囲まれた項目がセクション名である。今回は、このセクション名の一覧が取得したいのである。
これを実現するにはWindowsAPIのGetPrivateProfileSectionNames()関数を使えば良いのだが、C#にはこの機能はない。
そこでC#からはプラットフォーム呼び出しでWindowsAPIの関数を叩くことになる。
実際のコードは以下のようになった。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; using System.IO; namespace PInvokeLesson { public partial class Form1 : Form { [DllImport("kernel32.dll")] static extern int GetPrivateProfileSectionNames( IntPtr lpszReturnBuffer, uint nSize, string lpFileName); public Form1() { InitializeComponent(); } // Windowsフォーム アプリケーション // プロジェクト初期状態のフォームにボタンを一つ追加し、 // そのクリックイベントハンドラからプログラムは開始する。 private void button1_Click(object sender, EventArgs e) { String path = Application.StartupPath + Path.DirectorySeparatorChar + "test.ini"; if (File.Exists(path)) { IntPtr ptr = Marshal.StringToHGlobalAnsi(new String('\0', 1024)); int length = GetPrivateProfileSectionNames(ptr, 1024, path); if (0 < length) { String result = Marshal.PtrToStringAnsi(ptr, length); Array.ForEach<String>(result.Split('\0'), s => Console.WriteLine(s)); } Marshal.FreeHGlobal(ptr); } } } }
36行目、StringToHGlobalAnsi()メソッドでアンマネージの文字列を確保している。
こうした場合は必ず後で開放する必要がある。それをしているのが47行目のFreeHGlobal()である。
プラットフォーム呼び出しを行うと、メモリ領域の取得と開放にも気をつけなくてはいけない。
プログラムの実行フォルダに、先の例が記述されたtest.iniファイルを作成し、実行すると以下のように表示される。
Bob
John
Mike
Ken
Alice
プラットフォーム呼び出しの宣言は以下のサイトを参考にした。
http://www.pinvoke.net/default.aspx/kernel32/getprivateprofilesectionnames.html
このサイトには(おそらく)全てのWindowsAPIのプラットフォーム呼び出しの宣言をどう書けば良いかが載っているから、
とても参考になる。
ピンバック: 【C#】iniファイルの情報を取得する – ザワプロ!