c# winform读写INI文件

5次阅读
没有评论

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就不会这样了,无论中间 打开了哪个盘的文件,启动路径都是和程序路径一致