项目开发中遇到了需要调用硬件设备读取卡片信息的需求
项目开发中遇到了需要调用硬件设备读取卡片信息的需求,由于是第一次接触这种设计调试硬件的开发需求,因此一路磕磕绊绊,最后总算完成了任务,在此梳理记录下完整的开发流程。
注:需要有硬件相关的开发文档与 ***.dll 动态库文件
—————————————————————————————————————————————
在代码开发前需要先学习了解清楚此硬件设备提供的动态库文件中都设计到哪些接口,每个接口的作用都是什么,具体的硬件开发流程又是怎样的。
然后再代码中通过"DllImport"将对应的动态库接口一一定义(需要using System.Runtime.InteropServices),首先需要定义系统自带 “kernel32” 库的加载库函数方法"LoadLibrary"(“LoadLibrary”方法的入参“strDllName”就是需要加载的动态库 ***.dll文件的路径加名称),然后再定义硬件动态库接口函数,以读卡设备的打开串口接口(CommOpen)为例:
/// <summary>
/// 加载库函数
/// </summary>
/// <param name="strDllName"></param>
/// <returns></returns>
[DllImport("kernel32", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
public static extern int LoadLibrary(string strDllName);
//打开串口
[DllImport("CRT_310.dll")]
public static extern UInt32 CommOpen(string port);
然后在代码对应模块先加载库函数,加载成功后再调用对应的接口即可,代码如下所示:
/// <summary>
/// 就诊卡读卡
/// </summary>
/// <returns></returns>
public VisitCardInfo CRTReader()
{
VisitCardInfo visitCardInfo = new VisitCardInfo();
UInt32 Hdle = 0; // 门诊卡读卡器串口号字符串
try
{
VisitCard visitCard_Data = new VisitCard();
int nRet = CRT310.LoadLibrary("CRT_310.dll");
if (nRet == 0)
{
WriteLog.writeLog("CRT_310: 未找到CRT_310.dll文件!", "");
visitCardInfo.msg = "CRT_310:未找到CRT_310.dll文件!";
visitCardInfo.code = -1;
return visitCardInfo;
}
else
{
// 1.串口初始化, 打开串口
Hdle = CRT310.CommOpen("COM1");
if (Hdle == 0)
{
// 串口打开失败,直接返回错误
WriteLog.writeLog("CRT_310: 串口打开失败, 串口号:", Hdle.ToString());
visitCardInfo.msg = "CRT_310:串口打开失败";
visitCardInfo.code = -1;
return visitCardInfo;
}
WriteLog.writeLog("CRT_310: 串口打开成功, 串口号:", Hdle.ToString());
// 初始化 1扇区 0块 RF_InitValue
CmdRFInitValue(0x01, 0x00, out string msg, Hdle);
if (!string.IsNullOrEmpty(msg))
{
// 初始化失败
WriteLog.writeLog("CRT_310: 初始化失败! 错误信息为:", msg);
visitCardInfo.msg = "CRT_310:" + msg;
visitCardInfo.code = -1;
CRT310.CommClose(Hdle);
return visitCardInfo;
}
// 检查是否是M1卡片,
int res = RF_DetectCard(Hdle);
if (res == -1)
{
WriteLog.writeLog("CRT_310: 检查是否是M1卡片失败,串口号为0!:", "");
visitCardInfo.msg = "CRT_310:检查是否是M1卡片失败,串口号为0!";
visitCardInfo.code = -1;
CRT310.CommClose(Hdle);
return visitCardInfo;
}
else if (res != 0)
{
// 返回对应具体错误 (0X4E) 寻卡不成功 (0X45) 卡机内无卡 (0X57) 卡不在允许操作的位置上。
if (res == 0x4e)
{
visitCardInfo.msg = "CRT_310:寻卡不成功!";
}
else if (res == 0x45)
{
visitCardInfo.msg = "CRT_310:卡机内无卡!";
}
else if (res == 0x57)
{
visitCardInfo.msg = "CRT_310:卡不在允许操作的位置上!";
}
WriteLog.writeLog("CRT_310: 检查是否是M1卡片失败,对应的错误码为:", res.ToString());
visitCardInfo.code = -1;
CRT310.CommClose(Hdle);
return visitCardInfo;
}
WriteLog.writeLog("CRT_310: 开始验证密码!", "");
// 验证扇区密码
int keyResult = RF_LoadSecKey(Hdle);
if (keyResult != 0)
{
// 密码验证失败,返回错误码
WriteLog.writeLog("CRT_310: 密码验证失败,对应的错误码为:", keyResult.ToString());
visitCardInfo.msg = "CRT_310: 验证扇区密码失败!";
visitCardInfo.code = -1;
CRT310.CommClose(Hdle);
return visitCardInfo;
}
// 读取卡号 卡号存储在 01扇区 00块
int resCode = RFReadBlock(1, 0, out string StrBuf,Hdle);
if (resCode != 0)
{
// 读卡失败
WriteLog.writeLog("CRT_310: 读取卡号失败,错误信息为:", StrBuf);
visitCardInfo.msg = "CRT_310:读取卡号失败!";
visitCardInfo.code = -1;
CRT310.CommClose(Hdle);
return visitCardInfo;
}
else
{
// 返回卡号
WriteLog.writeLog("CRT_310: 读取卡号成功,就诊卡卡号为:", StrBuf);
visitCard_Data.ID = StrBuf;
visitCardInfo.msg = "CRT_310:读卡成功!";
visitCardInfo.code = 0;
visitCardInfo.data = visitCard_Data;
visitCardInfo.totalNumber = 1;
CRT310.CommClose(Hdle);
return visitCardInfo;
}
}
}
catch (Exception ex)
{
WriteLog.writeLog("CRT_310: 读取卡片信息出错!错误信息为:", ex.Message.ToString());
visitCardInfo.msg = "CRT_310:读取卡片信息出错!";
visitCardInfo.code = -1;
CRT310.CommClose(Hdle);
return visitCardInfo;
}
}