C#读写ini文件
调用winAPI 实现ini文件操作
- dll路径:C:\Windows\System32\kernel32.dll;
- 若调用失败可查看dll是否存在以及环境变量(C:\Windows\System32)是否已设置
- 静态类编写如下
文件接纳默认路径,若需要改变,调用之前请先更新文件路径
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Runtime.InteropServices;
- namespace BasicExercises
- {
- /***
- * ini文件样式
- * [配置项]
- * 属性1 = 属性值
- * 属性2 = 属性值
- * ...
- *
- * CharSet定义的时候使用了什么类型,在使用相关方法时必须要使用相应的类型
- * 例如 GetPrivateProfileSectionNames声明为CharSet.Auto,那么就应该使用 Marshal.PtrToStringAuto来读取相关内容
- * 如果使用的是CharSet.Ansi,就应该使用Marshal.PtrToStringAnsi来读取内容
- * **/
- class IniConfigHelper
- {
- static string iniFilePath = Environment.CurrentDirectory+"config.ini";
- public static string IniFilePath { get => iniFilePath; set => iniFilePath = value; }
- /***
- * 调用winAPI 实现ini文件操作
- * dll路径:C:\Windows\System32\kernel32.dll,若调用失败可查看dll是否存在以及环境变量(C:\Windows\System32)是否已设置
- * 以下是API函数
- ***/
- /// <summary>
- /// 写入ini文件:将指定的键和值写到指定的节点,如果已经存在则替换
- /// </summary>
- /// <param name="section">节点名称</param>
- /// <param name="key">键,null也直接写入</param>
- /// <param name="value">值,null也直接写入</param>
- /// <param name="filePath">ini文件路径</param>
- /// <returns>0失败/其他成功</returns>
- //[DllImport("kernel32", CharSet = CharSet.Auto)]
- //private static extern long WritePrivateProfileString(string section, string key, string value, string filePath);
- /// <summary>
- /// 写入ini文件:将指定的键和值写到指定的节点,如果已经存在则替换
- /// </summary>
- /// <param name="section">节点名称</param>
- /// <param name="key">键,null则删除指定的节点及其所有的项目</param>
- /// <param name="value">值,null则删除指定节点中指定的键</param>
- /// <param name="filePath">ini文件路径</param>
- /// <returns>操作是否成功</returns>
- [DllImport("kernel32", CharSet = CharSet.Auto)]
- private static extern bool WritePrivateProfileString(string section, string key, string value, string filePath);
- /// <summary>
- /// 将指定的键值对写到指定的节点,如果已经存在则替换。
- /// </summary>
- /// <param name="section">节点,如果不存在此节点,则创建此节点</param>
- /// <param name="keyValue">Item键值对,多个用\0分隔,形如key1=value1\0key2=value2
- /// 如果为string.Empty,则删除指定节点下的所有内容,保留节点
- /// 如果为null,则删除指定节点下的所有内容,并且删除该节点
- /// 该方法无脑写入,遇"\0"换行写入
- /// </param>
- /// <param name="filePath"></param>
- /// <returns>操作成功与否</returns>
- [DllImport("kernel32", CharSet = CharSet.Auto)]
- private static extern bool WritePrivateProfileSection(string section, string keyValue, string filePath);
- /// <summary>
- /// 调用winAPI读取ini文件
- /// </summary>
- /// <param name="section">节点名称</param>
- /// <param name="key">键</param>
- /// <param name="def">值(未读取到数据时设置的默认返回值)</param>
- /// <param name="result">读取的结构值</param>
- /// <param name="size">读取的缓冲区大小</param>
- /// <param name="filePath">ini路径</param>
- /// <returns>读取到的字节数量</returns>
- [DllImport("kernel32", CharSet = CharSet.Auto)]
- private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder result, int size, string filePath);
- /// <summary>
- /// 获取所有节点名称(Section)
- /// </summary>
- /// <param name="ptrResultBuffer">存放节点名称的内存地址,每个节点之间使用\0分隔</param>
- /// <param name="nSize">内存大小</param>
- /// <param name="filePath">ini文件路径</param>
- /// <returns>内容的实际长度,为0表示没有内容,为nSize-2表示内存大小不够</returns>
- [DllImport("kernel32", CharSet = CharSet.Auto)]
- private static extern uint GetPrivateProfileSectionsNames(IntPtr lpResultBuffer,uint nSize,string filePath);
- /// <summary>
- /// 获取某个指定节点(Section)中所有KEY和Value
- /// </summary>
- /// <param name="section">节点名称</param>
- /// <param name="lpReturnedString">返回值的内存地址,每个之间使用\0分隔</param>
- /// <param name="nSize">内存大小</param>
- /// <param name="filePath">ini文件地址</param>
- /// <returns></returns>
- [DllImport("kernel32", CharSet = CharSet.Auto)]
- private static extern uint GetPrivateProfileSection(string section, IntPtr lpReturnedString, uint nSize, string filePath);
- /***
- * 调用winAPI 实现ini文件操作
- * 以下是API对应的调用函数封装
- ***/
- /// <summary>
- /// 写入ini,指定节点下单键值对写入
- /// </summary>
- /// <param name="section"></param>
- /// <param name="key"></param>
- /// <param name="value"></param>
- /// <returns>操作成功与否</returns>
- public static bool WriteToIni(string section, string key, string value)
- {
- if (string.IsNullOrEmpty(section))
- {
- return false;
- //throw new ArgumentException("必须指定节点名称",section);
- }
- if (string.IsNullOrEmpty(key))
- {
- return false;
- //throw new ArgumentException("必须指定key值",key);
- }
- if (string.IsNullOrEmpty(value))
- {
- return false;
- //throw new ArgumentException("值不能为空",value);
- }
- return WritePrivateProfileString(section, key, value, iniFilePath);
- }
- /// <summary>
- /// 删除指定节点下指定键
- /// </summary>
- /// <param name="section">节点</param>
- /// <param name="key">键</param>
- /// <returns>操作成功与否</returns>
- public static bool DeleteKey(string section, string key)
- {
- if (string.IsNullOrEmpty(section))
- {
- return false;
- //throw new ArgumentException("必须指定节点名称",section);
- }
- if (string.IsNullOrEmpty(key))
- {
- return false;
- //throw new ArgumentException("必须指定key值",key);
- }
- return WritePrivateProfileString(section, key, null, iniFilePath);
- }
- /// <summary>
- /// 删除指定节点
- /// </summary>
- /// <param name="section">节点</param>
- /// <returns>操作成功与否</returns>
- public static bool DeleteSection(string section)
- {
- if (string.IsNullOrEmpty(section))
- {
- return false;
- //throw new ArgumentException("必须指定节点名称",section);
- }
- return WritePrivateProfileString(section, null, null, iniFilePath);
- }
- /// <summary>
- /// 清空指定节点
- /// </summary>
- /// <param name="section">节点</param>
- /// <returns>操作成功与否</returns>
- public static bool EmptySection(string section)
- {
- if (string.IsNullOrEmpty(section))
- {
- return false;
- //throw new ArgumentException("必须指定节点名称",section);
- }
- return WritePrivateProfileSection(section,string.Empty,iniFilePath);
- }
- /// <summary>
- /// 写入ini,指定节点下多个键值对写入
- /// </summary>
- /// <param name="section">节点</param>
- /// <param name="keyValue">键值对,形如key1=value1\0key2=value2 </param>
- /// <returns></returns>
- public static bool WriteToIniSection(string section, string keyValue)
- {
- if (string.IsNullOrEmpty(section))
- {
- return false;
- //throw new ArgumentException("必须指定节点名称",section);
- }
- if (string.IsNullOrEmpty(keyValue))
- {
- return false;
- //throw new ArgumentException("键值对不能为空",keyValue);
- }
- return WritePrivateProfileSection(section, keyValue, iniFilePath);
- }
-
- /// <summary>
- /// 读取ini,section和key不能为null
- /// </summary>
- /// <param name="section">节点</param>
- /// <param name="key">键</param>
- /// <returns>null或读取结果</returns>
- public static string ReadFromIni(string section,string key)
- {
- if (string.IsNullOrEmpty(section))
- {
- return null;
- //throw new ArgumentException("必须指定节点名称", section);
- }
- if (string.IsNullOrEmpty(key))
- {
- return null;
- //throw new ArgumentException("必须指定key值", key);
- }
- int size = 1024;
- StringBuilder builder = new StringBuilder(size);
- //string def = "";
- int result = GetPrivateProfileString(section, key, "", builder, size, iniFilePath);
- return builder.ToString();
- }
- /// <summary>
- /// 获取ini文件所有节点
- /// </summary>
- /// <returns>所有节点,没有内容返回string[0]</returns>
- public static string[] GetAllSections()
- {
- uint MAX_BUFFER = 32767;
- string[] sections = new string[0];
- //申请内存
- IntPtr pReturnedStr = Marshal.AllocCoTaskMem((int)MAX_BUFFER * sizeof(char));
- //读取内容
- uint nSize = GetPrivateProfileSectionsNames(pReturnedStr, MAX_BUFFER, iniFilePath);
- if (nSize != 0 && nSize != MAX_BUFFER - 2)
- {
- //读取内存内存
- string returnedStr = Marshal.PtrToStringAuto(pReturnedStr, (int)nSize);
- //转换成string[]格式
- sections = returnedStr.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
- }
- //释放内存
- Marshal.FreeCoTaskMem(pReturnedStr);
- return sections;
- }
- /// <summary>
- /// 获取指定节点下的所有key、value;形式key=value
- /// </summary>
- /// <param name="section">指定节点</param>
- /// <returns>指定节点的所有条目,空则返回string[0]</returns>
- public static string[] GetAllKeyValueBySection(string section)
- {
- if (string.IsNullOrEmpty(section))
- {
- return null;
- //throw new ArgumentException("必须指定节点名称", section);
- }
- uint MAX_BUFFER = 32767;
- string[] items = new string[0];
- //分配内存
- IntPtr pReturnedStr = Marshal.AllocCoTaskMem((int)MAX_BUFFER * sizeof(char));
- uint nSize = GetPrivateProfileSection(section, pReturnedStr, MAX_BUFFER, iniFilePath);
- if (nSize != 0 && nSize != MAX_BUFFER - 2)
- {
- //读取内存内容
- string returnedStr = Marshal.PtrToStringAuto(pReturnedStr, (int)nSize);
- 每个节点之间用\0分隔,末尾有一个\0
- items = returnedStr.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
- }
- //释放内存
- Marshal.FreeCoTaskMem(pReturnedStr);
- return items;
- }
- }
- }
复制代码- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- namespace BasicExercises
- {
- public partial class TestForm : Form
- {
- public TestForm()
- {
- InitializeComponent();
- }
- private void btnTestIni_Click(object sender, EventArgs e)
- {
-
- string userSection = "用户";
- string userNameKey = "Name";
- string testSection = "测试节点";
- string keyValue = "用户1=苏\0密码=苏\0用户2=林\0密码=林";
- //ini写入
- txtBoxMsg.Text = "";
- txtBoxMsg.Text += "测试写入以下内容:\r\n[" + userSection + "]\r\n" + userNameKey + " = 测试用户";
- bool IsWriteSec = IniConfigHelper.WriteToIni(userSection, userNameKey, "测试用户");
- if (IsWriteSec)
- {
- txtBoxMsg.Text += "\r\n写入成功!";
- }
- //多个键值对写入
- // \0 在C#中代表结束字符,不会被窗体输出
- txtBoxMsg.Text += "\r\n" + keyValue;
- IsWriteSec = IniConfigHelper.WriteToIniSection(testSection, keyValue);
- if (IsWriteSec)
- {
- txtBoxMsg.Text += "\r\n写入成功!";
- }
- //ini读取指定键
- string value = IniConfigHelper.ReadFromIni(userSection, userNameKey);
- txtBoxMsg.Text += "\r\n读取结果:" + value;
- //获取ini所有节点
- string[] sectionItems = IniConfigHelper.GetAllKeyValueBySection(testSection);
- string allSection = "";
- foreach (string item in sectionItems)
- {
- allSection += item;
- }
- txtBoxMsg.Text += "\r\n获取ini所有节点:" + allSection;
- //获取ini指定节点下的所有key和value
- string[] items = IniConfigHelper.GetAllKeyValueBySection(testSection);
- string msg = "";
- foreach (string item in items)
- {
- msg += item;
- }
- txtBoxMsg.Text += "\r\n获取ini指定节点下的所有key和value:" + msg;
- //删除指定key
- IsWriteSec = IniConfigHelper.DeleteKey(userSection, userNameKey);
- if (IsWriteSec)
- {
- txtBoxMsg.Text += "\r\n删除" + "[" + userSection + "]下的键:" + userNameKey + "成功";
- }
- //删除指定节点
- IsWriteSec = IniConfigHelper.DeleteSection(userSection);
- if (IsWriteSec)
- {
- txtBoxMsg.Text += "\r\n删除" + "[" + userSection + "]节点成功";
- }
- IsWriteSec = IniConfigHelper.DeleteSection(testSection);
- if (IsWriteSec)
- {
- txtBoxMsg.Text += "\r\n删除" + "[" + testSection + "]节点成功";
- }
- }
- }
- }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |