后来不相信,直接使用其自带的一个读卡程序以及其他语言开发的测试,都会出现这种问题,有时候读不到10次,有时候多几次,也会自动关闭程序。而出现这种情况,全部是通过调用支持动态库中的Syn_ReadMsg函数进行读取的,这说明此函数本身有问题。最后改成调用Syn_ReadBaseMsg函数,就解决了这个莫名其妙的问题。
Syn_ReadBaseMsg函数与Syn_ReadMsg函数的区别是,后者是直接将读出的信息进行了格式化(以结构体返回)并生成了图片文件,而前者是通过将信息和图片以2个指针返回,需要开发人员自行处理。
以下是相关函数代码,仅供参考。
[DllImport("SynIDCardAPI.dll", EntryPoint = "Syn_ReadBaseMsg", CharSet = CharSet.Ansi)]
public static extern int Syn_ReadBaseMsg(int iPort, IntPtr pucCHMsg, ref uint puiCHMsgLen, IntPtr pucPHMsg, ref uint puiPHMsgLen, int iIfOpen);
/// <summary>
/// 读取身份证基本信息
/// </summary>
/// <param name="CardMsg"></param>
/// <param name="errStr"></param>
/// <returns></returns>
public static bool ReadCard(out ZbsoftInterface.IDCardData CardMsg,
out string errStr)
{
CardMsg = new ZbsoftInterface.IDCardData();
errStr = "";
int nRet;
byte[] pucIIN = new byte[4];
byte[] pucSN = new byte[8];
#region 获取读卡器
if (nPort == 0)
{
if (!FindDrivers(out errStr))
{
if (string.IsNullOrEmpty(errStr))
errStr = "没有找到读卡器";
return false;
}
}
#endregion
if (Syn_OpenPort(nPort) == 0)
{
if (Syn_SetMaxRFByte(nPort, 80, 0) == 0)
{
nRet = Syn_StartFindIDCard(nPort, ref pucIIN[0], 0);
nRet = Syn_SelectIDCard(nPort, ref pucSN[0], 0);
string cardMsg = new string(' ', 256); //身份证基本信息返回长度为256
string imgMsg = new string(' ', 1024); //身份证图片信息返回长度为1024
IntPtr msg = Marshal.StringToHGlobalAnsi(cardMsg); //身份证基本信息
IntPtr img = Marshal.StringToHGlobalAnsi(imgMsg); //身份证图片
try
{
uint mLen = 0;
uint iLen = 0;
nRet = Syn_ReadBaseMsg(nPort, msg, ref mLen, img, ref iLen, 0);
if (nRet == 0)
{
string card = Marshal.PtrToStringUni(msg);
char[] cartb = card.ToCharArray();
CardMsg.Name = (new string(cartb, 0, 15)).Trim();
CardMsg.Sex = new string(cartb, 15, 1);
CardMsg.Nation = new string(cartb, 16, 2);
CardMsg.Born = new string(cartb, 18, 8);
CardMsg.Address = (new string(cartb, 26, 35)).Trim();
CardMsg.IDCardNo = new string(cartb, 61, 18);
CardMsg.GrantDept = (new string(cartb, 79, 15)).Trim();
CardMsg.UserLifeBegin = new string(cartb, 94, 8);
CardMsg.UserLifeEnd = new string(cartb, 102, 8);
return true;
}
else
{
errStr = "读取身份证信息错误";
}
}
catch (Exception e) { errStr = e.Message; }
finally
{
Marshal.FreeHGlobal(msg);
Marshal.FreeHGlobal(img);
}
}
else
{
errStr = "SetMaxRFByte出错";
}
}
else
{
errStr = "打开端口失败";
}
return false;
}
/// <summary>
/// 自动查询读卡器
/// </summary>
/// <param name="err">错误信息</param>
/// <returns></returns>
public static bool FindDrivers(out string err)
{
int i = 0;
err = "";
try
{
i = Syn_FindReader();
}
catch (Exception e)
{
err = e.ToString();
return false;
}
if (i > 0)
{
nPort = i;
}
else
{
nPort = 0;
return false;
}
return true;
}