getprivateprofilestring和writeprivateprofilestring是windows api中专用于ini文件读写的函数,仅用于兼容16位windows应用,现代程序应优先使用注册表;二者不区分大小写但空格敏感,自动处理ansi/unicode编码、注释及值内等号,无需手动解析。

直接用 Windows API 的 GetPrivateProfileString 和 WritePrivateProfileString 是最稳妥、最兼容的方案,尤其在 .NET Framework 或需要与传统 Windows 软件行为对齐时。 它不依赖第三方包,跳过注释、处理嵌套等号、大小写归一化全由系统保证——你只管传参,不用操心边界逻辑。
为什么不能直接用 File.ReadAllLines + 字符串分割
看似简单,实际踩坑密集:
- 值中含等号(如
path=C:\a=b\c)会被误切,只认第一个等号为分隔符才是 Windows 行为 - 节名和键名默认不区分大小写,但手写
.Contains("[Section]")会大小写敏感匹配失败 - 以
;或#开头的整行注释,若用Split('=')处理,可能把注释行当键值对解析 - ANSI 编码(如 GBK)文件在 UTF-16 环境下读取会乱码,而 API 自动按系统 ACP 解码
GetPrivateProfileString 必须注意的三个参数陷阱
返回值为 0 不代表“没找到”,常见误判点:
-
lpApplicationName和lpKeyName不能为null或空字符串,否则直接返回 0 —— 即使键存在也读不到 -
lpFileName必须是绝对路径;传"config.ini"会查当前工作目录,不是 EXE 所在目录,建议拼成Path.Combine(AppContext.BaseDirectory, "config.ini") -
lpReturnedString的缓冲区大小要预留结尾\0:传new StringBuilder(256)最多存 255 字符;超长时返回值为 255,但字符串被截断 —— 统一用new StringBuilder(32767)更安全
.NET Core / .NET 5+ 项目怎么绕过 kernel32.dll 限制
Windows API 在 Linux/macOS 不可用,此时必须换纯托管方案,但不能随便选:
- 不能用
Microsoft.VisualBasic.FileIO.IniParser:它仅限 .NET Framework,.NET 5+ 中已移除 - 不能用多数 NuGet INI 库:它们不模拟 Windows 的大小写归一化语义,也不处理值内等号,升级后行为可能突变
- 推荐轻量自研解析器,核心逻辑只需四步:
① 按行读取,跳过;/#开头行和空行
② 遇到[Section]记录当前节名(转小写)
③ 否则找第一个=,左边 trim 后转小写作键名,右边作值
④ 查询时统一将 section/key 转小写再比对
真实项目里最易被忽略的是编码与路径:INI 文件用记事本另存为“ANSI”才真正兼容 API;而调试时反复改文件却读不到新值,不是缓存问题,是进程没重启 —— Windows 的 INI API 确实有缓存,但调试阶段最省事的办法就是关掉再重开。










