using System;
using System.Runtime.InteropServices;
using System.Text;
public static class IniFile
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int GetPrivateProfileString(
string lpAppName, // Section
string lpKeyName, // Key
string lpDefault, // Default value
StringBuilder lpReturnedString, // Buffer
int nSize, // Buffer size
string lpFileName); // INI file path
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int WritePrivateProfileString(
string lpAppName, // Section
string lpKeyName, // Key
string lpString, // Value (null = delete key)
string lpFileName); // INI file path
private const int BufferSize = 1024;
///
/// 讀取值
///
public static string Read(string section, string key, string defaultValue, string filePath)
{
var sb = new StringBuilder(BufferSize);
GetPrivateProfileString(section, key, defaultValue, sb, BufferSize, filePath);
return sb.ToString();
}
///
/// 寫入值 (value=null 刪除鍵)
///
public static void Write(string section, string key, string value, string filePath)
{
WritePrivateProfileString(section, key, value, filePath);
}
///
/// 刪除整個 Section
///
public static void DeleteSection(string section, string filePath)
{
WritePrivateProfileString(section, null, null, filePath);
}
///
/// 讀取 Section 所有 Key
///
public static string[] ReadAllKeys(string section, string filePath)
{
var sb = new StringBuilder(BufferSize * 10);
GetPrivateProfileString(section, null, "", sb, sb.Capacity, filePath);
return sb.ToString().Split(new[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
}
///
/// 讀取 Section 所有 Key-Value
///
public static Dictionary ReadSection(string section, string filePath)
{
var dict = new Dictionary();
var keys = ReadAllKeys(section, filePath);
foreach (var key in keys)
dict[key] = Read(section, key, "", filePath);
return dict;
}
}
var iniPath = @"C:\Config\app.ini";
// 寫入
IniFile.Write("Database", "Host", "localhost", iniPath);
IniFile.Write("Database", "Port", "5432", iniPath);
IniFile.Write("Database", "User", "admin", iniPath);
IniFile.Write("App", "Version", "1.2.3", iniPath);
// 讀取
string host = IniFile.Read("Database", "Host", "127.0.0.1", iniPath);
int port = int.Parse(IniFile.Read("Database", "Port", "5432", iniPath));
// 列出 Section
var dbSettings = IniFile.ReadSection("Database", iniPath);
foreach (var kv in dbSettings)
Console.WriteLine($"{kv.Key} = {kv.Value}");
// 刪除 Key
IniFile.Write("Database", "User", null, iniPath);
// 刪除 Section
IniFile.DeleteSection("App", iniPath);
[Database]
Host=localhost
Port=5432
User=admin
[App]
Version=1.2.3
public class AppSettings
{
private readonly string _path;
public AppSettings(string path) => _path = path;
public string DbHost
{
get => IniFile.Read("Database", "Host", "localhost", _path);
set => IniFile.Write("Database", "Host", value, _path);
}
public int DbPort
{
get => int.Parse(IniFile.Read("Database", "Port", "5432", _path));
set => IniFile.Write("Database", "Port", value.ToString(), _path);
}
public string Version
{
get => IniFile.Read("App", "Version", "1.0.0", _path);
set => IniFile.Write("App", "Version", value, _path);
}
}
| 項目 | 說明 |
|---|---|
| 編碼 | ANSI (系統預設代碼頁),Unicode 需自行處理 (寫入 UTF-16 LE + BOM 並用 Wide 版 API) |
| 長度限制 | 單值 32KB (API 限制),Section/Key 名稱 255 字元 |
| 效能 | 每次呼叫都開啟/關閉檔案,頻繁存取建議快取或改用 XML/JSON |
| 並發 | 多進程寫入可能衝突,需外部鎖 (Mutex) 保護 |
| 跨平台 | 僅限 Windows (kernel32.dll),.NET Core 跨平台專案請改用 Microsoft.Extensions.Configuration.Ini |
// NuGet: Microsoft.Extensions.Configuration.Ini
using Microsoft.Extensions.Configuration;
var config = new ConfigurationBuilder()
.AddIniFile("appsettings.ini", optional: false, reloadOnChange: true)
.Build();
string host = config["Database:Host"]; // 以冒號分隔 Section:Key
int port = config.GetValue("Database:Port");
P/Invoke 封裝 Windows INI API 簡單直接,適合維護舊專案或輕量原生需求;新專案建議採用現代 Configuration 抽象層。