首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 讀寫 INI 設定檔:P/Invoke 封裝 kernel32.dll 完整實作

     編輯:關於C語言

背景

INI 檔案結構簡單 (區段/鍵/值),適合輕量級設定儲存。.NET Framework 未內建 INI 讀寫類別,需透過 P/Invoke 呼叫 Windows API kernel32.dll 中的 WritePrivateProfileString 與 GetPrivateProfileString。

API 簽章定義


using System.Runtime.InteropServices;
using System.Text;

public static class IniFile
{
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern long WritePrivateProfileString(
        string lpAppName,   // 區段名
        string lpKeyName,   // 鍵名
        string lpString,    // 值 (null 表示刪除鍵)
        string lpFileName); // INI 完整路徑

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern int GetPrivateProfileString(
        string lpAppName,
        string lpKeyName,
        string lpDefault,   // 找不到時的預設值
        StringBuilder lpReturnedString, // 接收緩衝區
        int nSize,          // 緩衝區大小 (含結束符)
        string lpFileName);
}

封裝輔助類別


public sealed class IniHelper
{
    private readonly string _path;
    public IniHelper(string filePath) => _path = filePath;

    public void Write(string section, string key, string value)
    {
        WritePrivateProfileString(section, key, value, _path);
    }

    public string Read(string section, string key, string defaultValue = "")
    {
        var sb = new StringBuilder(255);
        GetPrivateProfileString(section, key, defaultValue, sb, sb.Capacity, _path);
        return sb.ToString();
    }

    public void DeleteKey(string section, string key) => Write(section, key, null);
    public void DeleteSection(string section) => Write(section, null, null);
}

WinForms 完整範例

表單包含三個 TextBox (Database, Server, UserId)、兩個 Button (寫入/讀取)。


public partial class ConfigForm : Form
{
    private readonly IniHelper _ini;
    public ConfigForm()
    {
        InitializeComponent();
        // INI 檔放在執行檔同目錄
        string iniPath = Path.Combine(Application.StartupPath, "config.ini");
        _ini = new IniHelper(iniPath);
    }

    private void btnWrite_Click(object sender, EventArgs e)
    {
        _ini.Write("FiatDataBase", "DataBase", txtDatabase.Text);
        _ini.Write("FiatDataBase", "Server", txtServer.Text);
        _ini.Write("FiatDataBase", "UserId", txtUserId.Text);
        MessageBox.Show("寫入完成!");
    }

    private void btnRead_Click(object sender, EventArgs e)
    {
        try
        {
            txtDatabase.Text = _ini.Read("FiatDataBase", "DataBase");
            txtServer.Text = _ini.Read("FiatDataBase", "Server");
            txtUserId.Text = _ini.Read("FiatDataBase", "UserId");
        }
        catch (Exception ex)
        {
            MessageBox.Show("讀取失敗,請先設定:" + ex.Message);
        }
    }
}

生成的 INI 內容範例


[FiatDataBase]
DataBase=MyDb
Server=192.168.1.100
UserId=admin

注意事項與替代方案

  • 編碼:CharSet.Auto 依執行平台決定 Unicode/ANSI,建議明確指定 CharSet.Unicode 避免亂碼。
  • 緩衝區大小:GetPrivateProfileString 若值超過緩衝區會截斷,生產代碼建議動態擴充 (while (ret == size-1) size *= 2)。
  • 權限:寫入需對目錄有寫入權限 (如 Program Files 需管理員)。
  • 現代替代:.NET Core / 5+ 建議使用 Microsoft.Extensions.Configuration.Ini 或 JSON/XML/YAML 設定系統,跨平台且無 P/Invoke 相依。

結語

透過 kernel32.dll 讀寫 INI 是經典 WinForms 技巧,封裝後介面乾淨易用。但新專案優先考慮跨平台設定提供者。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved