C#中INI文件无原生支持,Windows平台推荐P/Invoke调用GetPrivateProfileString/WritePrivateProfileString;跨平台可选IniParser库,但需注意大小写、BOM及并发安全问题。

INI文件在C#里没有原生支持,得靠Windows API或第三方库
Windows平台下,GetPrivateProfileString 和 WritePrivateProfileString 是最直接的方案,但它们是Win32 API,需要P/Invoke调用。.NET本身(包括.NET Core/.NET 5+)不提供内置INI解析器——别指望ConfigurationBuilder加个.AddIniFile()就能用,它根本不支持INI格式。
如果你在跨平台项目里硬要用INI,得自己解析(比如按行分割、处理节名[Section]、键值对key=value),但要注意:注释(;或#)、空行、引号包裹值、转义等细节很容易出错。
用P/Invoke调用Win32 API是最轻量、最兼容的做法
适用于Windows桌面应用(WinForms/WPF),且不需要引入额外NuGet包。关键点:
-
GetPrivateProfileString返回的是实际读取的字符数,不是布尔值;若返回0,不一定失败——可能值为空字符串,得检查lpReturnedString首字节是否为\0 - 路径必须是绝对路径,相对路径会被解释为相对于当前进程工作目录,而非EXE所在目录
- 写入时若文件不存在,API会自动创建;但目录不存在则写入失败,不会自动建目录
- 所有字符串参数必须是
string(.NET会自动封送为LPCSTR),不要传StringBuilder给读取函数——除非你手动控制缓冲区大小
示例读取:
[DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
private static extern uint GetPrivateProfileString(
string lpAppName, string lpKeyName, string lpDefault,
StringBuilder lpReturnedString, uint nSize, string lpFileName);
var sb = new StringBuilder(256);
GetPrivateProfileString("Database", "Server", "", sb, (uint)sb.Capacity, @"C:\app\config.ini");
string server = sb.ToString();
用IniParser NuGet包更安全、可跨平台,但要注意默认行为
IniParser(NuGet包名:ini-parser)是目前最成熟的托管INI库,支持.NET Standard 2.0+,能处理注释、多行值、Unicode、节继承等。但它默认把键名转成小写——如果你的INI里有URL和url两个键,会被当成重复键覆盖。
解决方法:
- 构造
FileIniDataParser时传入new IniDataParser(new ParsingRules { CaseSensitive = true }) - 读取后修改再保存,必须调用
parser.WriteFile(path, data),不能只改data["Section"]["Key"]就完事——内存对象修改后不写回磁盘,等于没改 - 它不自动处理BOM,UTF-8无BOM文件读写最稳;带BOM的文件可能被误判编码,导致乱码
别忽略INI的固有缺陷:它不适合复杂配置
INI没有嵌套结构、没有数组原生语法、不支持类型推断(全是字符串)、无法表达null或布尔真伪(得靠约定如Enabled=1)。如果你的配置项开始出现Item1_Name、Item1_Value、Item2_Name……说明该换JSON或XML了。
另外,多个线程同时读写同一个INI文件极易损坏内容——Win32 API本身不加锁,IniParser也不做并发保护。真要并发访问,得自己加lock或用FileStream配FileShare.None做排他控制。










