C# 读写ini文件
开发工具 VS2010
创建ver.ini配置文件,与应用程序放在同一目录
文件格式
[authorName] author=weisico.com [version] ver=20160903
Windows系统自带的Win32的API函数GetPrivateProfileString()和WritePrivateProfileString()分别实现了对INI文件的读写操作,他们位于kernel32.dll下
C#所使用的.NET框架下的公共类库没有提供直接操作INI文件的类,所以这里调用API函数。 .Net框架下的类库是基于托管代码的,而API函数是基于非托管代码的,(在运行库的控制下执行的代码称作托管代码。相反,在运行库之外运 行的代码称作非托管代码。)如何实现托管代码与非托管代码之间的操作呢?.Net框架的System.Runtime.InteropServices命 名空间下提供各种各样支持COM interop及平台调用服务的成员,其中最重要的属性之一DllImportAttribute可以用来定义用于访问非托管API的平台调用方法,它提 供了对从非托管DLL导出的函数进行调用所必需的信息。
读操作
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string defVal, StringBuilder retVal, int size, string filePath);
section:要读取的段落名
key: 要读取的键
defVal: 读取异常的情况下的缺省值
retVal: key所对应的值,如果该key不存在则返回空值
size: 值允许的大小
filePath: INI文件的完整路径和文件名
写操作
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
section: 要写入的段落名
key: 要写入的键,如果该key存在则覆盖写入
val: key所对应的值
filePath: INI文件的完整路径和文件名
完整代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using Microsoft.Win32;
using System.IO;
using System.Runtime.InteropServices;
namespace RwIni
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
textBox1.Text = GetPrivateProfileString("version", "ver");
}
private void button2_Click(object sender, EventArgs e)
{
string iniValue = textBox1.Text;
if (iniValue != "")
{
WritePrivateProfileString("version", "ver", iniValue);
if (WritePrivateProfileString("version", "ver", iniValue) != 0)
{
MessageBox.Show("写入成功", "消息提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
else
{
MessageBox.Show("请输入版本号", "消息提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
/// <summary>
/// 软件安装路径,以此exe所在的路径为准。
/// </summary>
string installDirectory = null;
private string InstallDirectory
{
get
{
if (string.IsNullOrEmpty(installDirectory))
{
string sPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
installDirectory = Path.GetDirectoryName(sPath) + @"\";
}
return installDirectory;
}
}
private string startUpIniFileName = null;
public string StartUpIniFileName
{
get
{
if (string.IsNullOrEmpty(startUpIniFileName))
{
startUpIniFileName = InstallDirectory + "ver.ini";
}
return startUpIniFileName;
}
}
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section, string key, string value, string filePath);
/// <summary>
/// 从Ini文件获取数据
/// </summary>
/// <param name="section">应用程序</param>
/// <param name="key">键的名称</param>
/// <returns>键的值</returns>
private string GetPrivateProfileString(string section, string key)
{
int nCapacity = 255;
StringBuilder temp = new StringBuilder(nCapacity);
int i = GetPrivateProfileString(section, key, "", temp, nCapacity, StartUpIniFileName);
if (i < 0)
return "";
return temp.ToString();
}
/// <summary>
/// 向Ini文件中写入值
/// </summary>
/// <param name="section">应用程序</param>
/// <param name="key">键的名称</param>
/// <param name="value">键的值</param>
/// <returns>执行成功为True,失败为False。</returns>
public long WritePrivateProfileString(string section, string key, string value)
{
if (section.Trim().Length <= 0 || key.Trim().Length <= 0 || value.Trim().Length <= 0)
return 0;
return WritePrivateProfileString(section, key, value, StartUpIniFileName);
}
}
}
附
除直接使用外,还可以写一个IniFile类,对读写方法进行调用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
namespace 测试
{
/// <summary>
/// INI文件的操作类
/// </summary>
public class IniFile
{
public string Path;
public IniFile(string path)
{
this.Path = path;
}
#region 声明读写INI文件的API函数
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string defVal, StringBuilder retVal, int size, string filePath);
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string defVal, Byte[] retVal, int size, string filePath);
#endregion
/// <summary>
/// 写INI文件
/// </summary>
/// <param name="section">段落</param>
/// <param name="key">键</param>
/// <param name="iValue">值</param>
public void IniWriteValue(string section, string key, string iValue)
{
WritePrivateProfileString(section, key, iValue, this.Path);
}
/// <summary>
/// 读取INI文件
/// </summary>
/// <param name="section">段落</param>
/// <param name="key">键</param>
/// <returns>返回的键值</returns>
public string IniReadValue(string section, string key)
{
StringBuilder temp = new StringBuilder(255);
int i = GetPrivateProfileString(section, key, "", temp, 255, this.Path);
return temp.ToString();
}
/// <summary>
/// 读取INI文件
/// </summary>
/// <param name="Section">段,格式[]</param>
/// <param name="Key">键</param>
/// <returns>返回byte类型的section组或键值组</returns>
public byte[] IniReadValues(string section, string key)
{
byte[] temp = new byte[255];
int i = GetPrivateProfileString(section, key, "", temp, 255, this.Path);
return temp;
}
}
}
程序在调用IniFile类时需要实例化
//string path = Environment.CurrentDirectory + @"\Config.ini"; //指定ini文件的路径
string path = Application.StartupPath + @"\ver.ini"; //指定ini文件的路径
IniFile ini = new IniFile(path);
string verValue = ini.IniReadValue("version", "ver");//读取ini文件中键值
备注
System.Environment.CurrentDirectory的含义是获取或设置当前工作路径,而Application.StartupPath是获取程序启动路径,表面上看二者没什么区别,但实际还是有区别。System.Environment.CurrentDirectory获取的当前工作路径不一定真的就是程序所在路径。比如说程序放在桌面上启 动,但是中间用了一个OpenFileDialog打开了D盘名为weisico的文件夹下的某一个文件,那么CurrentDirectory就变成 D:\weisico了,所以如果想再获取程序启动文件夹的某一个文件就没用了,但是Application.StartupPath就不会这样了,无论中间 打开了哪个盘的文件,启动路径都是和程序路径一致