最近、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ファイルの情報を取得する – ザワプロ!