You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

294 lines
13 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace demo.ClassHelper.FileOperate
{
class IniHelper
{
/// <summary>
/// Windows API 对INI文件写方法
/// </summary>
/// <param name="lpAppName">要在其中写入新字串的段名。这个字串不区分大小写</param>
/// <param name="lpKeyName">要设置的项名或条目名。这个字串不区分大小写。用null可删除这个小节的所有设置项</param>
/// <param name="lpString">指定为这个项写入的字串值。用null表示删除这个项现有的字串</param>
/// <param name="lpFileName">初始化文件的名字。如果没有指定完整路径名则windows会在windows目录查找文件。如果文件没有找到则函数会创建它</param>
/// <returns></returns>
[DllImport("kernel32")]
public static extern long WritePrivateProfileString(string section, string key, string val, string strPath);
/// <summary>
/// 获取所有节点名称(Section)
/// </summary>
/// <param name="lpszReturnBuffer">存放节点名称的内存地址,每个节点之间用\0分隔</param>
/// <param name="nSize">内存大小(characters)</param>
/// <param name="lpFileName">Ini文件</param>
/// <returns>内容的实际长度,为0表示没有内容,为nSize-2表示内存大小不够</returns>
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern uint GetPrivateProfileSectionNames(IntPtr lpszReturnBuffer, uint nSize, string lpFileName);
/// <summary>
/// 获取某个指定节点(Section)中所有KEY和Value
/// </summary>
/// <param name="lpAppName">节点名称</param>
/// <param name="lpReturnedString">返回值的内存地址,每个之间用\0分隔</param>
/// <param name="nSize">内存大小(characters)</param>
/// <param name="lpFileName">Ini文件</param>
/// <returns>内容的实际长度,为0表示没有内容,为nSize-2表示内存大小不够</returns>
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern uint GetPrivateProfileSection(string lpAppName, IntPtr lpReturnedString, uint nSize, string lpFileName);
/// <summary>
/// 读取INI文件中指定的Key的值
/// </summary>
/// <param name="lpAppName">节点名称。如果为null,则读取INI中所有节点名称,每个节点名称之间用\0分隔</param>
/// <param name="lpKeyName">Key名称。如果为null,则读取INI中指定节点中的所有KEY,每个KEY之间用\0分隔</param>
/// <param name="lpDefault">读取失败时的默认值</param>
/// <param name="lpReturnedString">读取的内容缓冲区,读取之后,多余的地方使用\0填充</param>
/// <param name="nSize">内容缓冲区的长度</param>
/// <param name="lpFileName">INI文件名</param>
/// <returns>实际读取到的长度</returns>
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern uint GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, [In, Out] char[] lpReturnedString, uint nSize, string lpFileName);
/// Windows API 对INI文件字符串的读方法
/// </summary>
/// <param name="lpAppName">要在其中读取字符串的段名。这个字串不区分大小写</param>
/// <param name="lpKeyName">要读取数据的关键字名称。这个字串不区分大小写。</param>
/// <param name="lpDefault">当不存在指定关键字名称时,默认返回的字符串</param>
/// <param name="lpReturnedString">返回的字符串</param>
/// <param name="nSize">lpReturnedString参数的空间字节大小</param>
/// <param name="lpFileName">初始化文件的名字。如果没有指定完整路径名则windows会在windows目录查找文件。如果文件没有找到则函数会创建它</param>
/// <returns></returns>
[DllImport("kernel32")]
public static extern int GetPrivateProfileString(string section, string key, string def,
StringBuilder sb, int size, string strPath);
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string def, byte[] retVal, int size, string filePath);
//再一种声明使用string作为缓冲区的类型同char[]
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern uint GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, string lpReturnedString, uint nSize, string lpFileName);
/// <summary>
/// Windows API 对INI文件整数的读方法
/// </summary>
/// <param name="lpAppName">要在其中读取字符串的段名。这个字串不区分大小写</param>
/// <param name="lpKeyName">要读取数据的关键字名称。这个字串不区分大小写。用null可删除这个小节的所有设置项</param>
/// <param name="nDefault">当未能找到指定的关键字名称时,则返回的默认值</param>
/// <param name="lpFileName">初始化文件的名字。如果没有指定完整路径名则windows会在windows目录查找文件。如果文件没有找到则函数会创建它</param>
/// <returns></returns>
[DllImport("kernel32.dll", EntryPoint = "GetPrivateProfileInt", CharSet = CharSet.Unicode)]
public static extern int GetPrivateProfileInt(
string lpAppName,
string lpKeyName,
int nDefault,
string lpFileName);
/// <summary>
/// 写入配置文件
/// </summary>
/// <param name="strSection"></param>
/// <param name="strKey"></param>
/// <param name="strValue"></param>
public static void WriteToIni(string strSection, string strKey, string strValue, string strPath)
{
WritePrivateProfileString(strSection, strKey, strValue, strPath);
}
/// <summary>
/// 从配置文件中读取
/// </summary>
/// <param name="strSection"></param>
/// <param name="strKey"></param>
/// <returns></returns>
public static string ReadStrFromIni(string strSection, string strKey, string strPath)
{
StringBuilder stringBuilder = new StringBuilder(500);
GetPrivateProfileString(strSection.Trim(), strKey.Trim(), "", stringBuilder, 500, strPath);
return stringBuilder.ToString();
}
/// <summary>
/// 从配置文件中读取
/// </summary>
/// <param name="strSection"></param>
/// <param name="strKey"></param>
/// <returns></returns>
public static int ReadIntFromIni(string strSection, string strKey, string strPath)
{
int defualt = 0;
return GetPrivateProfileInt(strSection.Trim(), strKey.Trim(), defualt, strPath);
}
/// <summary>
/// 获取section下的keys
/// </summary>
/// <param name="Section"></param>
/// <param name="iniFilename"></param>
/// <returns></returns>
public static List<string> ReadSingleSection(string Section, string iniFilename)
{
List<string> result = new List<string>();
byte[] buf = new byte[65536];
int lenf = GetPrivateProfileString(Section, null, null, buf, buf.Length, iniFilename);
int j = 0;
for (int i = 0; i < lenf; i++)
if (buf[i] == 0)
{
result.Add(Encoding.Default.GetString(buf, j, i - j));
j = i + 1;
}
return result;
}
/// <summary>
/// 获取指定section下的values
/// </summary>
/// <param name="Section"></param>
/// <param name="iniFilename"></param>
/// <returns></returns>
public static List<string> ReadSectionValues(string Section, string iniFilename)
{
List<string> keys = new List<string>();
List<string> values = new List<string>();
byte[] buf = new byte[100];
keys = ReadSingleSection(Section, iniFilename);
for (int i = 0; i < keys.Count; i++ )
{
int len = GetPrivateProfileString(Section, keys[i], null, buf, buf.Length, iniFilename);
values.Add(Encoding.Default.GetString(buf,0,len));
Array.Clear(buf, 0, buf.Length);
}
return values;
}
/// <summary>
/// 读取INI文件中指定INI文件中的所有节点名称(Section)
/// </summary>
/// <param name="iniFile">Ini文件</param>
/// <returns>所有节点,没有内容返回string[0]</returns>
public static string[] INIGetAllSectionNames(string iniFile)
{
uint MAX_BUFFER = 32767; //默认为32767
string[] sections = new string[0]; //返回值
//申请内存
IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER * sizeof(char));
uint bytesReturned = GetPrivateProfileSectionNames(pReturnedString, MAX_BUFFER, iniFile);
if (bytesReturned != 0)
{
//读取指定内存的内容
string local = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned).ToString();
//每个节点之间用\0分隔,末尾有一个\0
sections = local.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
}
//释放内存
Marshal.FreeCoTaskMem(pReturnedString);
return sections;
}
/// <summary>
/// 获取INI文件中指定节点(Section)中的所有条目(key=value形式)
/// </summary>
/// <param name="iniFile">Ini文件</param>
/// <param name="section">节点名称</param>
/// <returns>指定节点中的所有项目,没有内容返回string[0]</returns>
public static string[] INIGetAllItems(string iniFile, string section)
{
//返回值形式为 key=value,例如 Color=Red
uint MAX_BUFFER = 32767; //默认为32767
string[] items = new string[0]; //返回值
//分配内存
IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER * sizeof(char));
uint bytesReturned = GetPrivateProfileSection(section, pReturnedString, MAX_BUFFER, iniFile);
if (!(bytesReturned == MAX_BUFFER - 2) || (bytesReturned == 0))
{
string returnedString = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned);
items = returnedString.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
}
Marshal.FreeCoTaskMem(pReturnedString); //释放内存
return items;
}
/// <summary>
/// 获取INI文件中指定节点(Section)中的所有条目的Key列表
/// </summary>
/// <param name="iniFile">Ini文件</param>
/// <param name="section">节点名称</param>
/// <returns>如果没有内容,反回string[0]</returns>
public static string[] INIGetAllItemKeys(string iniFile, string section)
{
string[] value = new string[0];
const int SIZE = 1024 * 10;
if (string.IsNullOrEmpty(section))
{
throw new ArgumentException("必须指定节点名称", "section");
}
char[] chars = new char[SIZE];
uint bytesReturned = GetPrivateProfileString(section, null, null, chars, SIZE, iniFile);
if (bytesReturned != 0)
{
value = new string(chars).Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
}
chars = null;
return value;
}
/// <summary>
/// 读取INI文件中指定KEY的字符串型值
/// </summary>
/// <param name="iniFile">Ini文件</param>
/// <param name="section">节点名称</param>
/// <param name="key">键名称</param>
/// <param name="defaultValue">如果没此KEY所使用的默认值</param>
/// <returns>读取到的值</returns>
public static string INIGetStringValue(string iniFile, string section, string key, string defaultValue)
{
string value = defaultValue;
const int SIZE = 1024 * 10;
if (string.IsNullOrEmpty(section))
{
throw new ArgumentException("必须指定节点名称", "section");
}
if (string.IsNullOrEmpty(key))
{
throw new ArgumentException("必须指定键名称(key)", "key");
}
StringBuilder sb = new StringBuilder(SIZE);
int bytesReturned = GetPrivateProfileString(section, key, defaultValue, sb, SIZE, iniFile);
if (bytesReturned != 0)
{
value = sb.ToString();
}
sb = null;
return value;
}
}
}