这份代码,主要是根据api文档来写的,文档上提供了各个方法的使用说明,并且有一个示例代码。以及网上找到的代码。
首先,需要2个dll,sdtapi.dll,用来读取身份证上的基本信息;WltRS.dll,用来解析照片,身份证上的照片。这两个文件放在bin目录的debug中,或者release中。然后对于sdtapi.dll该动态链接库,若用的是2004年左右的,需要一个temp.lib的授权文件;但是2005年左右的,则不需要了。
然后引入动态链接库中的方法,里面的方法都是参考网上的资料和文档写出来的。新建一个名叫DllMoudle的类,里面有7个方法,通过DllImport链接库导入,导入。方法主要是SDT_OpenPort,打开端口号和 SDT_ClosePort关闭端口号,SDT_StartFindIDCard开始找卡,SDT_SelectIDCard选择卡,以及SDT_ReadBaseMsg读取基本信息,和SDT_ReadBaseMsgToFile从文件中读取基本信息,以及GetBmp获取图片。
- public class DllMoudle
- {
- #region "dll声明"
- /// <summary>
- /// 打开串口/USB。
- /// </summary>
- /// <param name="iPort">[in] 整数, 表示端口号。 1-16(十进制)为串口,1001-1016(十进制)为USB口,缺省的一个USB 设备端口号是 1001。</param>
- /// <returns>0x90 打开端口成功;1 打开端口失败/端口号不合法</returns>
- [DllImport("sdtapi.dll", CallingConvention = CallingConvention.StdCall)]
- public static extern int SDT_OpenPort(int iPort);
- /// <summary>
- /// 关闭串口/USB。
- /// </summary>
- /// <param name="iPort">[in] 整数,表示端口号。</param>
- /// <returns>0x90 关闭端口成功。 0x01 端口号不合法</returns>
- [DllImport("sdtapi.dll", CallingConvention = CallingConvention.StdCall)]
- public static extern int SDT_ClosePort(int iPort);
- /// <summary>
- /// 读卡
- /// </summary>
- /// <param name="iPort"></param>
- /// <param name="pucManaInfo">证/卡芯片管理号, 4 个字节。</param>
- /// <param name="iIfOpen"></param>
- /// <returns>0x9f 找卡成功;0x80 找卡失败</returns>
- [DllImport("sdtapi.dll", CallingConvention = CallingConvention.StdCall)]
- public static extern int SDT_StartFindIDCard (int iPort, byte[] pucManaInfo,int iIfOpen);
- /// <summary>
- /// 选择卡
- /// </summary>
- /// <param name="iPort"></param>
- /// <param name="pucManaMsg">卡体管理号,28 字节。</param>
- /// <param name="iIfOpen"></param>
- /// <returns>0x90 读成功;其他 读失败(具体含义参见返回码表</returns>
- [DllImport("sdtapi.dll",CallingConvention = CallingConvention.StdCall)]
- public static extern int SDT_SelectIDCard (int iPort , byte[] pucManaMsg,int iIfOpen);
- /// <summary>
- /// 读取基本数据
- /// </summary>
- /// <param name="iPort"></param>
- /// <param name="pucCHMsg"></param>
- /// <param name="puiCHMsgLen"></param>
- /// <param name="pucPHMsg"></param>
- /// <param name="puiPHMsgLen"></param>
- /// <param name="iIfOpen"></param>
- /// <returns></returns>
- [DllImport("sdtapi.dll",CallingConvention = CallingConvention.StdCall)]
- public static extern int SDT_ReadBaseMsg(int iPort, byte[] pucCHMsg, ref UInt32 puiCHMsgLen, byte[] pucPHMsg, ref UInt32 puiPHMsgLen, int iIfOpen);
- /// <summary>
- /// 读取图片;
- /// </summary>
- /// <param name="file_name">wlt文件名,后缀是.wlt</param>
- /// <param name="Port"></param>
- /// <returns>1,正确;0,-1,-2,。。。-6</returns>
- [DllImport("WltRS.dll",CallingConvention = CallingConvention.StdCall)]
- public static extern int GetBmp(String file_name, int Port);
- [DllImport("sdtapi.dll")]
- public static extern int SDT_ReadBaseMsgToFile(int iPortID, string fileName1, ref UInt32 puiCHMsgLen, string fileName2, ref UInt32 puiPHMsgLen, int iIfOpen);
- #endregion
- }
现在这些方法就可以用了。
然后建立了一个实体clsEDZ,用来存放身份证上的基本信息。包括图片,二进制的和Image的。还有由于身份证上sex和nation读取到的都是code,根据code,拿到真正的值。如sex若是1,则是男;民族若是01,则是汉族。
- public class clsEDZ
- {
- private SortedList lstMZ = new SortedList();
- private string _Name; //姓名
- private string _Sex_Code; //性别代码
- private string _Sex_CName; //性别
- private string _IDC; //身份证号码
- private string _NATION_Code; //民族代码
- private string _NATION_CName; //民族
- private DateTime _BIRTH; //出生日期
- private string _ADDRESS; //住址
- private string _REGORG; //签发机关
- private DateTime _STARTDATE; //身份证有效起始日期
- private DateTime _ENDDATE; //身份证有效截至日期
- private string _Period_Of_Validity_Code; //有效期限代码,许多原来系统上面为了一代证考虑,常常存在这样的字段,二代证中已经没有了
- private string _Period_Of_Validity_CName; //有效期限
- private byte[] _PIC_Byte; //照片二进制
- private Image _PIC_Image; //照片
- public clsEDZ()
- {
- lstMZ.Add("01", "汉族");
- lstMZ.Add("02", "蒙古族");
- lstMZ.Add("03", "回族");
- lstMZ.Add("04", "藏族");
- lstMZ.Add("05", "维吾尔族");
- lstMZ.Add("06", "苗族");
- lstMZ.Add("07", "彝族");
- lstMZ.Add("08", "壮族");
- lstMZ.Add("09", "布依族");
- lstMZ.Add("10", "朝鲜族");
- lstMZ.Add("11", "满族");
- lstMZ.Add("12", "侗族");
- lstMZ.Add("13", "瑶族");
- lstMZ.Add("14", "白族");
- lstMZ.Add("15", "土家族");
- lstMZ.Add("16", "哈尼族");
- lstMZ.Add("17", "哈萨克族");
- lstMZ.Add("18", "傣族");
- lstMZ.Add("19", "黎族");
- lstMZ.Add("20", "傈僳族");
- lstMZ.Add("21", "佤族");
- lstMZ.Add("22", "畲族");
- lstMZ.Add("23", "高山族");
- lstMZ.Add("24", "拉祜族");
- lstMZ.Add("25", "水族");
- lstMZ.Add("26", "东乡族");
- lstMZ.Add("27", "纳西族");
- lstMZ.Add("28", "景颇族");
- lstMZ.Add("29", "柯尔克孜族");
- lstMZ.Add("30", "土族");
- lstMZ.Add("31", "达翰尔族");
- lstMZ.Add("32", "仫佬族");
- lstMZ.Add("33", "羌族");
- lstMZ.Add("34", "布朗族");
- lstMZ.Add("35", "撒拉族");
- lstMZ.Add("36", "毛南族");
- lstMZ.Add("37", "仡佬族");
- lstMZ.Add("38", "锡伯族");
- lstMZ.Add("39", "阿昌族");
- lstMZ.Add("40", "普米族");
- lstMZ.Add("41", "塔吉克族");
- lstMZ.Add("42", "怒族");
- lstMZ.Add("43", "乌孜别克族");
- lstMZ.Add("44", "俄罗斯族");
- lstMZ.Add("45", "鄂温克族");
- lstMZ.Add("46", "德昂族");
- lstMZ.Add("47", "保安族");
- lstMZ.Add("48", "裕固族");
- lstMZ.Add("49", "京族");
- lstMZ.Add("50", "塔塔尔族");
- lstMZ.Add("51", "独龙族");
- lstMZ.Add("52", "鄂伦春族");
- lstMZ.Add("53", "赫哲族");
- lstMZ.Add("54", "门巴族");
- lstMZ.Add("55", "珞巴族");
- lstMZ.Add("56", "基诺族");
- lstMZ.Add("57", "其它");
- lstMZ.Add("98", "外国人入籍");
- }
- public string Name
- {
- get { return _Name; }
- set { _Name = value; }
- }
- public string Sex_Code
- {
- get { return _Sex_Code; }
- set
- {
- _Sex_Code = value;
- switch (value)
- {
- case "1":
- Sex_CName = "男";
- break;
- case "2":
- Sex_CName = "女";
- break;
- }
- }
- }
- public string Sex_CName
- {
- get { return _Sex_CName; }
- set { _Sex_CName = value; }
- }
- public string IDC
- {
- get { return _IDC; }
- set { _IDC = value; }
- }
- public string NATION_Code
- {
- get { return _NATION_Code; }
- set
- {
- _NATION_Code = value;
- if (lstMZ.Contains(value))
- NATION_CName = lstMZ[value].ToString();
- }
- }
- public string NATION_CName
- {
- get { return _NATION_CName; }
- set { _NATION_CName = value; }
- }
- public DateTime BIRTH
- {
- get { return _BIRTH; }
- set { _BIRTH = value; }
- }
- public string ADDRESS
- {
- get { return _ADDRESS; }
- set { _ADDRESS = value; }
- }
- public string REGORG
- {
- get { return _REGORG; }
- set { _REGORG = value; }
- }
- public DateTime STARTDATE
- {
- get { return _STARTDATE; }
- set { _STARTDATE = value; }
- }
- public DateTime ENDDATE
- {
- get { return _ENDDATE; }
- set
- {
- _ENDDATE = value;
- if (_ENDDATE == DateTime.MaxValue)
- {
- _Period_Of_Validity_Code = "3";
- _Period_Of_Validity_CName = "长期";
- }
- else
- {
- if (_STARTDATE != DateTime.MinValue)
- {
- switch (value.AddDays(1).Year - _STARTDATE.Year)
- {
- case 5:
- _Period_Of_Validity_Code = "4";
- _Period_Of_Validity_CName = "5年";
- break;
- case 10:
- _Period_Of_Validity_Code = "1";
- _Period_Of_Validity_CName = "10年";
- break;
- case 20:
- _Period_Of_Validity_Code = "2";
- _Period_Of_Validity_CName = "20年";
- break;
- }
- }
- }
- }
- }
- public string Period_Of_Validity_Code
- {
- get { return _Period_Of_Validity_Code; }
- set { _Period_Of_Validity_Code = value; }
- }
- public string Period_Of_Validity_CName
- {
- get { return _Period_Of_Validity_CName; }
- set { _Period_Of_Validity_CName = value; }
- }
- public byte[] PIC_Byte
- {
- get { return _PIC_Byte; }
- set { _PIC_Byte = value; }
- }
- public Image PIC_Image
- {
- get { return _PIC_Image; }
- set { _PIC_Image = value; }
- }
- }
- public partial class readIdCard : Form
- {
- //接收身份证信息的实体
- private clsEDZ objEDZ = new clsEDZ();
- //构造函数
- public readIdCard()
- {
- InitializeComponent();
- }
- //读卡
- private void button1_Click(object sender, EventArgs e)
- {
- usbIdCard();
- }
- private void usbIdCard() {
- //声明变量
- DialogResult dr;
- int iRet = 0x90; //返回码
- int iPort = 1001; //端口号
- int iIfOpen = 1; //是否需要打开端口
- byte[] pubManaInfo = new byte[255]; //身份证管理号信息
- byte[] pubManaMsg = new byte[255]; //
- byte[] pubCHMsg = new byte[512]; //文字信息
- byte[] pubPHMsg = new byte[3024]; //照片信息
- byte[] pubFPMsg = new byte[1024]; //指纹信息
- UInt32 puiCHMsgLen = 0; //文字信息的长度
- UInt32 puiPHMsgLen = 0; //照片信息的长度
- //打开端口
- if (iIfOpen == 0) {
- iRet = DllMoudle.SDT_OpenPort(iPort);
- //若打开端口不成功
- if (iRet != 0x90) {
- MessageBox.Show("SDT_OpenPort Error,Error Code Is: " + iRet);
- //关闭端口
- DllMoudle.SDT_ClosePort(iPort);
- return;
- }
- }
- //找卡
- do {
- //开始找卡
- iRet = DllMoudle.SDT_StartFindIDCard(iPort, pubManaInfo, iIfOpen);
- if(iRet == 0x9f){
- //找到之后,选择卡
- iRet = DllMoudle.SDT_SelectIDCard(iPort, pubManaMsg, iIfOpen);
- if (iRet == 0x90) {
- break;
- }
- }
- //若找不到卡,提示
- dr = MessageBox.Show("尚未找到卡,您是否想继续找卡?", "找卡提示",
- MessageBoxButtons.YesNo,
- MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2);
- }
- //一直找卡,直到取消找卡
- while ( dr == DialogResult.Yes);
- //读卡信息
- iRet = DllMoudle.SDT_ReadBaseMsg(iPort, pubCHMsg,ref puiCHMsgLen,pubPHMsg,ref puiPHMsgLen,iIfOpen);
- if (iRet != 0x90) {
- //不成功,关闭端口,退出
- MessageBox.Show("SDT_ReadBaseMsg Error,Error Code Is: " + iRet);
- closePort(iPort, iIfOpen);
- return;
- }
- //读卡成功
- //显示结果集
- textBox1.Text = System.Text.ASCIIEncoding.Unicode.GetString(pubCHMsg);
- //注意,在这里,用户必须有应用程序当前目录的读写权限
- //删除掉这些文件
- FileInfo objFile = new FileInfo("wz.txt");
- if (objFile.Exists)
- {
- objFile.Attributes = FileAttributes.Normal;
- objFile.Delete();
- }
- objFile = new FileInfo("zp.bmp");
- if (objFile.Exists)
- {
- objFile.Attributes = FileAttributes.Normal;
- objFile.Delete();
- }
- objFile = new FileInfo("zp.wlt");
- if (objFile.Exists)
- {
- objFile.Attributes = FileAttributes.Normal;
- objFile.Delete();
- }
- //将基本信息写到wz.txt中,将照片信息写到zp.wlt文件中
- iRet = DllMoudle.SDT_ReadBaseMsgToFile(iPort, "wz.txt", ref puiCHMsgLen, "zp.wlt", ref puiPHMsgLen, iIfOpen);
- if (iRet != 144)
- {
- iRet = DllMoudle.SDT_ClosePort(iPort);
- MessageBox.Show("读卡失败!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
- return;
- }
- //下面解析照片,注意,如果在C盘根目录下没有机具厂商的授权文件Termb.Lic,照片解析将会失败
- //用2表示usb口,1表示串口。将zp.wlt转换为照片zp.bmp。
- bool falg = true;
- if (falg)
- iRet = DllMoudle.GetBmp("zp.wlt", 2);
- else
- iRet = DllMoudle.GetBmp("zp.wlt", 1);
- switch (iRet)
- {
- case 0:
- MessageBox.Show("调用sdtapi.dll错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
- break;
- case 1: //正常
- break;
- case -1:
- MessageBox.Show("相片解码错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
- break;
- case -2:
- MessageBox.Show("wlt文件后缀错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
- break;
- case -3:
- MessageBox.Show("wlt文件打开错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
- break;
- case -4:
- MessageBox.Show("wlt文件格式错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
- break;
- case -5:
- MessageBox.Show("软件未授权!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
- break;
- case -6:
- MessageBox.Show("设备连接错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
- break;
- }
- //如果照片解析成功,则将照片,将从wz.txt中的内容赋值给二进制的bt
- iRet = DllMoudle.SDT_ClosePort(iPort);
- FileInfo f = new FileInfo("wz.txt");
- FileStream fs = f.OpenRead();
- byte[] bt = new byte[fs.Length];
- fs.Read(bt, 0, (int)fs.Length);
- fs.Close();
- //然后根据位数分割,获取到相应的值,前30为是姓名,31-32是性别的编码。等等依次类推
- objEDZ.Name = System.Text.UnicodeEncoding.Unicode.GetString(bt, 0, 30).Trim();
- objEDZ.Sex_Code = System.Text.UnicodeEncoding.Unicode.GetString(bt, 30, 2).Trim();
- objEDZ.NATION_Code = System.Text.UnicodeEncoding.Unicode.GetString(bt, 32, 4).Trim();
- string strBird = System.Text.UnicodeEncoding.Unicode.GetString(bt, 36, 16).Trim();
- objEDZ.BIRTH = Convert.ToDateTime(strBird.Substring(0, 4) + "年" + strBird.Substring(4, 2) + "月" + strBird.Substring(6) + "日");
- objEDZ.ADDRESS = System.Text.UnicodeEncoding.Unicode.GetString(bt, 52, 70).Trim();
- objEDZ.IDC = System.Text.UnicodeEncoding.Unicode.GetString(bt, 122, 36).Trim();
- objEDZ.REGORG = System.Text.UnicodeEncoding.Unicode.GetString(bt, 158, 30).Trim();
- string strTem = System.Text.UnicodeEncoding.Unicode.GetString(bt, 188, bt.GetLength(0) - 188).Trim();
- objEDZ.STARTDATE = Convert.ToDateTime(strTem.Substring(0, 4) + "年" + strTem.Substring(4, 2) + "月" + strTem.Substring(6, 2) + "日");
- strTem = strTem.Substring(8);
- if (strTem.Trim() != "长期")
- {
- objEDZ.ENDDATE = Convert.ToDateTime(strTem.Substring(0, 4) + "年" + strTem.Substring(4, 2) + "月" + strTem.Substring(6, 2) + "日");
- }
- else
- {
- objEDZ.ENDDATE = DateTime.MaxValue;
- }
- //找到zp.bmp照片
- objFile = new FileInfo("zp.bmp");
- //若找存在,则将照片通过文件流中督考imgbyte的二进制中,然后用Memorystream流中创建图片Image,
- //放到身份证的Image照片上;而imgbyte则放到照片的二进制中。最后将图片和memorystream都摧毁。
- if (objFile.Exists)
- {
- FileStream fss = new FileStream("zp.bmp", FileMode.Open);
- byte[] imgbyte = new byte[(int)objFile.Length];
- fss.Read(imgbyte, 0, (int)objFile.Length);
- fss.Close();
- MemoryStream ms = new MemoryStream(imgbyte);
- Image img = Image.FromStream(ms);
- objEDZ.PIC_Image = (Image)img.Clone();
- objEDZ.PIC_Byte = imgbyte;
- img.Dispose();
- ms.Dispose();
- }
- //最后界面显示值和照片
- textBox1.Text = textBox1.Text + objEDZ.Name+objEDZ.Sex_Code + objEDZ.NATION_Code + objEDZ.BIRTH + objEDZ.ADDRESS + objEDZ.IDC + objEDZ.REGORG + objEDZ.STARTDATE + objEDZ.ENDDATE;
- pictureBox1.Image = objEDZ.PIC_Image;
- }
- /// <summary>
- /// 关闭端口
- /// </summary>
- /// <param name="iPort">端口号</param>
- /// <param name="iIfOpen">是否开启</param>
- private void closePort(int iPort,int iIfOpen) {
- if (iIfOpen == 0)
- {
- DllMoudle.SDT_ClosePort(iPort);
- }
- }
- }
扫描二维码关注公众号,回复:
2023901 查看本文章