硬件管理平台-硬件网关-插件模块-配置文件
硬件管理平台-硬件网关-插件模块-配置文件
上一篇仅仅将反射的基础模块进行了添加,不过还有很重要的一个配置文件还未进行添加,本文将讲述ini配置文件的添加方式
何谓配置文件
例如在HardwareGatewayService项目中读取App.config文件或log4net读取config.xml文件相同,本项目也需要添加一些无法在公司初始化的方法,例如上位机的系统地址,客户项目的具体信息,例如心跳时间,客户联系人或者本项目的唯一主键等。
配置文件类似于数据库,但是没有数据库那么复杂,说白了就是文件存储的简单数据库,相比数据库而言,配置文件比较简单,不过效率不高,只能存储部分以key,value形式存储的数据。
ini操作类
一般使用ini配置文件主要是使用微软自带的kernel32,通过动态引用kernel32,将WritePrivateProfileString、GetPrivateProfileString、GetPrivateProfileSectionNames、GetPrivateProfileSection放到公共类中进而去形成一个公共的ini操作类即可。
在公共包的UtilsLibaray项目中,添加ini文件夹,在ini文件夹中添加IniOpt.cs。
public class IniOpt
{
#region 私有变量
/// <summary>
/// 设置读取value时默认字数为1024
/// </summary>
private const int n_StrSize = 1024;
/// <summary>
/// 设置读取section时默认的大小
/// 就是[]到下一个[]的所有信息,包括key和value
/// </summary>
private const int n_SecSize = 32768;
/// <summary>
/// 设置读取key时默认的大小
/// </summary>
private const int n_KeySize = 256;
/// <summary>
/// 要读取的ini文件位置,这里我们设置与硬件网关同级
/// </summary>
private string FFullFileName = GlobalVar.LocalPath + "\\config.ini";
#endregion
#region 还是对其他类非可见的方法,保护方法
/// <summary>
/// 判断ini配置文件是否存在
/// </summary>
/// <returns></returns>
protected bool FileAssigned()
{
return !string.IsNullOrEmpty(FFullFileName) &&
File.Exists(FFullFileName);
}
#region API declaration
//调用系统dll的方法
//其中CharSet.Unicode为中文设置。
//使用这个有个好处,如果认为修改ini文件,该方法获得值是乱码
[DllImport("kernel32", CharSet = CharSet.Unicode)] // 0 = fail
protected static extern long WritePrivateProfileString(string ASection, string AKey, string AVal, string AFileName);
[DllImport("kernel32", CharSet = CharSet.Unicode)] // returns the length
protected static extern long GetPrivateProfileString(string ASection, string AKey, string ADefault, StringBuilder ARetVal, uint ASize, string AFileName);
[DllImport("kernel32", CharSet = CharSet.Unicode)] // returns the length
protected static extern long GetPrivateProfileSectionNames(byte[] ANames, uint ABuffSize, string AFileName);
[DllImport("kernel32", CharSet = CharSet.Unicode)] // returns the length
protected static extern int GetPrivateProfileSection(string ASection, byte[] AContents, int ABuffSize, string AFileName);
#endregion
#endregion
#region 对外暴露方法
#region 读取部分
/// <summary>
/// 通过尝试读取key获得value,如果没有则返回默认值
/// </summary>
/// <param name="ASection">区域,就是[]的信息</param>
/// <param name="AKey">key</param>
/// <param name="ADefault">默认返回值</param>
/// <returns></returns>
public virtual string ReadString(string ASection, string AKey, string ADefault)
{
if (!FileAssigned())
return ADefault;
StringBuilder sbTemp = new StringBuilder(n_StrSize);
//判断是否读取到
if (GetPrivateProfileString(ASection, AKey, ADefault, sbTemp, n_StrSize, FFullFileName) > 0)
{
//读取到返回ini中的value
return sbTemp.ToString();
}
else
{
//返回默认值
return ADefault;
}
}
/// <summary>
/// 获取int的相关值
/// </summary>
/// <param name="ASection"></param>
/// <param name="AKey"></param>
/// <param name="ADefault"></param>
/// <returns></returns>
public virtual int ReadInt(string ASection, string AKey, int ADefault)
{
string intStr = ReadString(ASection, AKey, "");
try
{
return int.Parse(intStr);
}
catch (InvalidCastException)
{
return ADefault;
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 获取bool的值
/// </summary>
/// <param name="ASection"></param>
/// <param name="AKey"></param>
/// <param name="ADefault"></param>
/// <returns></returns>
public virtual bool ReadBool(string ASection, string AKey, bool ADefault)
{
int blnVal = ReadInt(ASection, AKey, Convert.ToInt32(ADefault));
return (blnVal != 0);
}
/// <summary>
/// 获取double
/// </summary>
/// <param name="ASection"></param>
/// <param name="AKey"></param>
/// <param name="ADefault"></param>
/// <returns></returns>
public virtual double ReadDouble(string ASection, string AKey, double ADefault)
{
string dblStr = ReadString(ASection, AKey, "");
try
{
return Convert.ToDouble(dblStr);
}
catch (InvalidCastException)
{
return ADefault;
}
catch (Exception ex)
{
throw ex;
}
}
public virtual DateTime ReadDateTime(string ASection, string AKey, DateTime ADefault)
{
string dtStr = ReadString(ASection, AKey, "");
try
{
return Convert.ToDateTime(dtStr);
}
catch (InvalidCastException)
{
return ADefault;
}
catch (Exception ex)
{
throw ex;
}
}
#endregion
#region 写部分
/// <summary>
/// 根据key写入value数值
/// </summary>
/// <param name="ASection"></param>
/// <param name="AKey"></param>
/// <param name="AValue"></param>
/// <returns></returns>
public virtual bool WriteString(string ASection, string AKey, string AValue)
{
if (!FileAssigned())
return false;
long R = WritePrivateProfileString(ASection, AKey, AValue, FFullFileName);
return (R > 0);
}
public virtual bool WriteInt(string ASection, string AKey, int AValue)
{
return WriteString(ASection, AKey, Convert.ToString(AValue));
}
public virtual bool WriteBool(string ASection, string AKey, bool AValue)
{
string[] blnValues = { "0", "1" };
return WriteString(ASection, AKey, blnValues[Convert.ToInt32(AValue)]);
}
public virtual bool WriteDouble(string ASection, string AKey, double AValue)
{
return WriteString(ASection, AKey, Convert.ToString(AValue));
}
public virtual bool WriteDateTime(string ASection, string AKey, DateTime AValue)
{
return WriteString(ASection, AKey, Convert.ToString(AValue));
}
#endregion
#region Management
/// <summary>
/// 判断是否存在[]这个section
/// </summary>
/// <param name="ASection"></param>
/// <returns></returns>
public virtual bool SectionExists(string ASection)
{
if (!FileAssigned())
return false;
StringCollection names;
if (ReadSectionNames(out names))
{
return names.IndexOf(ASection) > -1;
}
else
{
return false;
}
}
/// <summary>
/// 判断section和key是否存在,不管value是否为空
/// </summary>
/// <param name="ASection"></param>
/// <param name="AKey"></param>
/// <returns></returns>
public virtual bool ValueExists(string ASection, string AKey)
{
if (!FileAssigned())
return false;
StringCollection keys;
if (ReadSectionKeys(ASection, out keys))
{
return keys.IndexOf(AKey) > -1;
}
else
{
return false;
}
}
/// <summary>
/// 删除setiong中的key
/// </summary>
/// <param name="ASection"></param>
/// <param name="AKey"></param>
/// <exception cref="IOException"></exception>
public virtual void DeleteKey(string ASection, string AKey)
{
if (!FileAssigned())
return;
long retVal = WritePrivateProfileString(ASection, AKey, null, FFullFileName);
if (retVal == 0)
{
throw new IOException(string.Format("Unable to write to {0}", FFullFileName));
}
}
/// <summary>
/// 清空section下的key和value
/// </summary>
/// <param name="ASection"></param>
/// <exception cref="IOException"></exception>
public virtual void EraseSection(string ASection)
{
if (!FileAssigned())
return;
long retVal = WritePrivateProfileString(ASection, null, null, FFullFileName);
if (retVal == 0)
{
throw new IOException(string.Format("Unable to write to {0}", FFullFileName));
}
}
// 获取所有的section
public virtual bool ReadSectionNames(out StringCollection ASectionNames)
{
ASectionNames = new StringCollection();
if (!FileAssigned())
return false;
byte[] buff = new byte[n_SecSize];
long retCnt = GetPrivateProfileSectionNames(buff, n_SecSize, FFullFileName);
if (retCnt > 0)
{
int iPos = 0;
for (int iCnt = 0; iCnt < retCnt; iCnt++)
{
if (buff[iCnt] == 0)
{
string name = ASCIIEncoding.Default.GetString(buff, iPos, iCnt).Trim();
iPos = iCnt + 1;
if (!string.IsNullOrEmpty(name))
{
ASectionNames.Add(name);
}
}
}
return ASectionNames.Count > 0;
}
else
{
return false;
}
}
// 获取section下的所有内容.
public virtual bool ReadSectionContents(string ASection, out StringCollection AContents)
{
AContents = new StringCollection();
if (!FileAssigned())
return false;
byte[] buff = new byte[n_KeySize];
int retCnt = GetPrivateProfileSection(ASection, buff, n_KeySize, FFullFileName);
if (retCnt > 0)
{
int iPos = 0;
for (int iCnt = 0; iCnt < retCnt; iCnt++)
{
if (buff[iCnt] == 0)
{
string key = ASCIIEncoding.Default.GetString(buff, iPos, iCnt).Trim();
iPos = iCnt + 1;
if (!string.IsNullOrEmpty(key))
{
AContents.Add(key);
}
}
}
return AContents.Count > 0;
}
else
{
return false;
}
}
// 获取section下的所有key信息
public virtual bool ReadSectionKeys(string ASection, out StringCollection AKeys)
{
AKeys = new StringCollection();
if (!FileAssigned())
return false;
if (ReadSectionContents(ASection, out AKeys))
{
for (int i = 0; i < AKeys.Count; i++)
{
string sKey = AKeys[i];
int iPos = sKey.IndexOf("=");
AKeys[i] = sKey.Substring(0, iPos);
}
return AKeys.Count > 0;
}
else
{
return false;
}
}
// 获取section下的所有key以及对应的value
public virtual bool ReadSectionValues(string ASection, out StringCollection AValues)
{
AValues = new StringCollection();
if (!FileAssigned())
return false;
if (ReadSectionContents(ASection, out AValues))
{
for (int i = 0; i < AValues.Count; i++)
{
string sValue = AValues[i];
int iPos = sValue.IndexOf("=");
AValues[i] = sValue.Substring(iPos + 1);
}
return AValues.Count > 0;
}
else
{
return false;
}
}
#endregion
#endregion
}
ini操作类的使用
在PluginManage的构造方法中添加ini读写操作,主要目的是将操作的配置信息获得到。
//ini配置文件的操作代码
IniOpt iniOpt = new IniOpt();
String ip = iniOpt.ReadString("SETTING", "IP", "127.0.0.1");
String port = iniOpt.ReadString("SETTING", "PORT", "80");
String defaultUrl = iniOpt.ReadString("SETTING", "DEFAULTURL", "");
String methodUrl = iniOpt.ReadString("SETTING", "METHODURL", "gateway/api/GetFunction");
// 获得网关主键
gatewayId = iniOpt.ReadString("SETTING", "ID", "");
// 获取上位机的调用url
defaultURL = GlobalVar.GetDefaultURL(ip, port, defaultUrl, methodUrl);
其中gatewayId和defaultURL声明如下
/// <summary>
/// 上传的url
/// </summary>
readonly String defaultURL = "";
/// <summary>
/// 网关主键
/// </summary>
readonly String gatewayId = "";
ini对应的写入方法在网关配置程序中添加。