实际开发中,如果需要读取身份证信息,就涉及到身份证读卡器开发了,最近项目中刚好用到,借此与大家分享下开发过程。
身份证读卡器市面上有很多种,华旭、中控、华大等等,其开发原理大同小异,本次以华旭读卡器为例。
//身份证信息结构
public class IDcardInfo
{
public string CardNo
{
get;
set;
}
public string Name
{
get;
set;
}
public string Sex
{
get;
set;
}
public DateTime Birthday
{
get;
set;
}
public string Nation
{
get;
set;
}
public string IDNumber
{
get;
set;
}
public string Address
{
get;
set;
}
public string Department
{
get;
set;
}
public string EffectData
{
get;
set;
}
public string Expire
{
get;
set;
}
public string ImagePath
{
get;
set;
}
}
//接口,因可能涉及不同设备,固都继承此接口
public interface IIDcardReader
{
IDcardInfo ReadInfo();
}
//设备烈性
public enum EnumIDReaderDevice
{
[Description("无")]
None = 0,
[Description("华旭")]
HuaXu = 1,
[Description("华大")]
HuaDa = 3,
[Description("中控")]
ZK = 4
}
//设备工厂
public sealed class DeviceFactory
{
private static EnumIDReaderDevice _ReaderDevice = EnumIDReaderDevice.None;
public static IIDcardReader CreateIDcardReader()
{
string config = "1";//设备以华旭为例
if (_ReaderDevice == EnumIDReaderDevice.None)
{
if (config == "1")
{
_ReaderDevice = EnumIDReaderDevice.HuaXu;
}
else if (config == "3")
{
_ReaderDevice = EnumIDReaderDevice.HuaDa;
}
else if (config == "4")
{
_ReaderDevice = EnumIDReaderDevice.ZK;
{
}
IIDcardReader result = null;
switch (_ReaderDevice)
{
case EnumIDReaderDevice.HuaXu:
result = new IDcardReaderHX();
break;
case EnumIDReaderDevice.HuaDa:
result = new SSSE32Reader();
break;
case EnumIDReaderDevice.ZK:
result = new ZKReader();
break;
}
return result;
}
}
//设备类
public class IDcardReaderHX : IIDcardReader
{
public IDcardInfo ReadInfo()
{
byte[] pucManaInfo = new byte[255];
byte[] pucManaMsg = new byte[255];
byte[] array = new byte[255];
byte[] array2 = new byte[1024];
byte[] array3 = new byte[1024];
uint puiCHMsgLen = 0u;
uint puiPHMsgLen = 0u;
int num = 0;
int num2 = SDT_OpenPort(1001);
num = SDT_StartFindIDCard(1001, pucManaInfo, 1);
num = SDT_SelectIDCard(1001, pucManaMsg, 1);
num = SDT_ReadBaseMsg(1001, array, ref puiCHMsgLen, array2, ref puiPHMsgLen, 1);
SDT_ClosePort(1001);
if (num != 144)
{
return null;
}
IDCARDINFO iDCARDINFO = (IDCARDINFO)IDCARDINFO.BytesToStruct(array, typeof(IDCARDINFO));
string text = iDCARDINFO.ID.Trim() + ".wlt";
bool flag = writeFile(array2, (int)puiPHMsgLen, text);
iDCARDINFO.ImagePath = iDCARDINFO.ID.Trim() + ".bmp";
if (!File.Exists(iDCARDINFO.ImagePath))
{
int bmp = GetBmp(Encoding.UTF8.GetBytes(text), 1);
}
IDcardInfo dcardInfo = new IDcardInfo();
dcardInfo.CardNo = iDCARDINFO.ID.Trim();
dcardInfo.Name = iDCARDINFO.name.Trim();
dcardInfo.Sex = iDCARDINFO.Sex.Trim();
dcardInfo.Birthday = DateTime.ParseExact(iDCARDINFO.BIRTH.Trim(), "yyyyMMdd", CultureInfo.CurrentCulture);
dcardInfo.Nation = iDCARDINFO.NATION.Trim();
dcardInfo.IDNumber = iDCARDINFO.ID.Trim();
dcardInfo.Address = iDCARDINFO.ADDRESS.Trim();
dcardInfo.Department = iDCARDINFO.ISSUE.Trim();
dcardInfo.EffectData = iDCARDINFO.EXPER_STA.Trim();
dcardInfo.Expire = iDCARDINFO.EXPER_END.Trim();
dcardInfo.ImagePath = iDCARDINFO.ImagePath;
return dcardInfo;
}
private static bool writeFile(byte[] buf, int pucaddMsgLen, string fname)
{
try
{
FileStream fileStream = new FileStream(fname, FileMode.OpenOrCreate);
fileStream.Write(buf, 0, pucaddMsgLen);
fileStream.Close();
return true;
}
catch
{
return false;
}
}
//居民身份证信息获取接口 可自行查找下载
[DllImport("sdtapi_x32/sdtapi.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
private static extern int SDT_OpenPort(int iPort);
[DllImport("sdtapi_x32/sdtapi.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, EntryPoint = "SDT_OpenPort")]
private static extern int SDT_ClosePort(int iPort);
[DllImport("sdtapi_x32/sdtapi.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
private static extern int SDT_StartFindIDCard(int iPort, byte[] pucManaInfo, int iIfOpen);
[DllImport("sdtapi_x32/sdtapi.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
private static extern int SDT_SelectIDCard(int iPort, byte[] pucManaMsg, int iIfOpen);
[DllImport("sdtapi_x32/sdtapi.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
private static extern int SDT_ReadBaseMsg(int iPort, byte[] pucCHMsg, ref uint puiCHMsgLen, byte[] pucPHMsg, ref uint puiPHMsgLen, int iIfOpen);
[DllImport("sdtapi_x32/WltRS.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
private static extern int GetBmp(byte[] Wlt_File, int intf);
[DllImport("sdtapi_x32/sdtapi.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
private static extern int SDT_ReadNewAppMsg(int iPort, byte[] pucCHMsg, ref uint puiCHMsgLen, int iIfOpen);
}
//最后项目中读取身份证实际信息
public IDcardInfo ReadCardInfo()
{
IDcardInfo cardInfo = null;
tyr
{
IIDcardReader cardReader = DeviceFactory.CreateIDcardReader();
if (cardReader == null)
{
MessageBox.Show("未检测到读取设备!");
return;
}
cardInfo = iIDcardReader.ReadInfo();
return cardinfo;
}
}