当前位置: 代码迷 >> 综合 >> 二代身份证阅读器 C#、JAVA调用教程
  详细解决方案

二代身份证阅读器 C#、JAVA调用教程

热度:11   发布时间:2024-02-27 21:11:45.0

型号:普天CPIDMR02/TG身份证阅读器

SDK版本:2020

(我这不提供下载,自己咨询卖家,或者网上自己找,SDK 厂家不二次封装的机器理论通用)

新老版本区别:

 多了外国人永久居留身份证、港澳台居民居住证识别

注:

机器不用做升级(事实上也没法自己升级)

本SDK和教程仅支持普天2013年以后的机器,若不知道什么时候出厂,看下序列号

普天机器序列号印在背面,一般是这样 0503XXXX....,0503后面4位就是出厂时间,若你手上是老机器,请使用旧版的SDK。

 

开发需要文件:

cardapi7.dll    DLL接口
sdtapi.dll    
WltRS.dll    相片解码
license.dat    授权文件

使用说明:

1.cardapi7.dll、sdtapi.dll、WltRS.dll、license.dat四个文件放在同一个路径中。该路径可以与应用程序所在的路径不同。
2.程序在运行的过程中应该将license.dat复制到C盘根目录。

手动安装USB驱动:
Win7为例。右击“计算机”->“管理”->“设备管理器”,寻找“其他设备”。找到了之后点击左侧小箭头,看下面有没有“未知设备”。如果有,右击“未知设备”->“更新驱动程序软件”->“浏览计算机以查找驱动程序软件”。输入客户端或者OCX控件安装路径。

一般默认安装路径如下:
32位系统:C:\Program Files\Shpte\SamDriver\x86
64位系统:C:\Program Files (x86)\Shpte\SamDriver\x64

 

常见问题:

SDK目前手上只有32位版本。开发.net应用程序时必须将“目标平台”设置为“x86”。开发Java应用程序时必须使用32位JDK和JRE。

如果调用IdcrInitialize后返回0x118,即“创建授权文件失败”,请手动将license.dat复制到C盘根目录(装控件时会自己装,但是windows7和10,为了安全考虑,往C盘根目录写文件时都会提示需要管理员权限,那么有可能会失败)。

 

C#

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;namespace CSharpDemo
{class CardApi{[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 8)]public class PERSONINFOW{[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]public string name;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]public string sexCode;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]public string sex;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]public string ethnicCode;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]public string ethnic;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]public string birthDate;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 36)]public string address;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]public string idNumber;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]public string issuer;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]public string effectDate;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]public string expiryDate;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 36)]public string appendInfo;}[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 8)]public class FOREIGNERINFOW{[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 62)]public string englishName;//60[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]public string sexCode;		//1[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]public string sex;			//男/M 女/F[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]public string prNumber;	//15[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]public string countryCode;	//3[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]public string country;	//加拿大/CAN[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]public string chineseName;//15汉字[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]public string effectDate;	//8[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]public string expiryDate;	//8[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]public string birthDate;	//8[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]public string version;		//2[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]public string issuerCode;	//4[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)]public string issuer;		//公安部/Ministry of Public Security}[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 8)]public class COMPATRIOTINFOW{[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]public string name;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]public string sexCode;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]public string sex;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]public string birthDate;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 36)]public string address;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]public string idNumber;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]public string issuer;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]public string effectDate;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]public string expiryDate;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]public string passNumber;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]public string issueCount;}[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 8)]public class FPINFOW{[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]public byte[] fpData1;[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]public byte[] fpData2;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]public string fingerName1;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]public string fingerName2;}[DllImport("cardapi7.dll", EntryPoint = "IdcrInitialize",CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]public static extern int IdcrInitialize(uint dwFlags);[DllImport("cardapi7.dll", EntryPoint = "IdcrOpen",CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]public static extern int IdcrOpen(ref int piPort, uint dwBaudRate, uint dwCmdIntv, int iBpPort, ref IntPtr ppRD);[DllImport("cardapi7.dll", EntryPoint = "IdcrValidate",CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]public static extern int IdcrValidate(IntPtr pRD, int bReadFP, ref int piCardType, int bRepeatRead);[DllImport("cardapi7.dll", EntryPoint = "IdcrGetIDInfoW",CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]public static extern int IdcrGetIDInfoW(IntPtr pRD, [In, Out]PERSONINFOW pTextInfo, string pszPhotoPath, [In, Out]FPINFOW pFPInfo);[DllImport("cardapi7.dll", EntryPoint = "IdcrGetPRInfoW",CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]public static extern int IdcrGetPRInfoW(IntPtr pRD, [In, Out]FOREIGNERINFOW pTextInfo, string pszPhotoPath, [In, Out]FPINFOW pFPInfo);[DllImport("cardapi7.dll",EntryPoint="IdcrGetHMTInfoW",CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]public static extern int IdcrGetHMTInfoW(IntPtr pRD, [In,Out]COMPATRIOTINFOW pTextInfo, string pszPhotoPath, [In,Out]FPINFOW pFPInfo);[DllImport("cardapi7.dll", EntryPoint = "IdcrClose",CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]public static extern void IdcrClose(IntPtr pRD);[DllImport("cardapi7.dll", EntryPoint = "IdcrFinalize",CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]public static extern void IdcrFinalize();[DllImport("cardapi7.dll", EntryPoint = "IdcrGetErrorDescW",CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]public static extern void IdcrGetErrorDescW(StringBuilder pszBuffer, uint nBufLen, int nErrorCode);}
}

前台form关键代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;namespace CSharpDemo
{public partial class Form1 : Form{const int TYPE_IDCARD = 1;const int TYPE_PRCARD = 2;const int TYPE_HMTCARD = 3;IntPtr pRD = IntPtr.Zero;int cardType = 0;Image photo = null;CardApi.PERSONINFOW person;CardApi.FOREIGNERINFOW foreigner;CardApi.COMPATRIOTINFOW compatriot;CardApi.FPINFOW fpInfo;string birthDate = null;string validTerm = null;public Form1(){InitializeComponent();person = new CardApi.PERSONINFOW();foreigner = new CardApi.FOREIGNERINFOW();compatriot = new CardApi.COMPATRIOTINFOW();fpInfo = new CardApi.FPINFOW();}protected override void OnHandleCreated(EventArgs e){base.OnHandleCreated(e);int error = CardApi.IdcrInitialize(1);if (error != 0){StringBuilder errorstring=new StringBuilder(200);ShowErrorDesc(error);//MessageBox.Show("初始化失败" + errorstring.ToString(), "", MessageBoxButtons.OK, MessageBoxIcon.Stop);}}void SetRect(ref RectangleF rect, float x, float y, float width, float height){rect.X = x;rect.Y = y;rect.Width = width;rect.Height = height;}private void ShowErrorDesc(int result){StringBuilder buffer = new StringBuilder(32);CardApi.IdcrGetErrorDescW(buffer, 32, result);txtErrorCode.Text = buffer.ToString();}private void btnOpen_Click(object sender, EventArgs e){int result;int port = 0;if (pRD == IntPtr.Zero){result = CardApi.IdcrOpen(ref port, 115200, 0, 0, ref pRD);ShowErrorDesc(result);}}private void btnRead_Click(object sender, EventArgs e){int result;int readFP;string photoPath;if (pRD == IntPtr.Zero){return;}Clear();readFP = ckReadFP.Checked ? 1 : 0;photoPath = Path.GetTempPath() + "\\photo.bmp";result = CardApi.IdcrValidate(pRD, readFP, ref cardType, 1);if (0 == result){if (TYPE_IDCARD == cardType){if (ckReadFP.Checked){result = CardApi.IdcrGetIDInfoW(pRD, person, photoPath, fpInfo);}else{result = CardApi.IdcrGetIDInfoW(pRD, person, photoPath, null);}if (0 == result){birthDate = ConvertDate(person.birthDate, 1);validTerm = ConvertDate(person.effectDate, 2);validTerm += '-';validTerm += ConvertDate(person.expiryDate, 2);}}else if (TYPE_PRCARD == cardType){if (ckReadFP.Checked){result = CardApi.IdcrGetPRInfoW(pRD, foreigner, photoPath, fpInfo);}else{result = CardApi.IdcrGetPRInfoW(pRD, foreigner, photoPath, null);}if (0 == result){birthDate = ConvertDate(foreigner.birthDate, 2);validTerm = ConvertDate(foreigner.effectDate, 2);validTerm += '-';validTerm += ConvertDate(foreigner.expiryDate, 2);}}else if (TYPE_HMTCARD == cardType){if (ckReadFP.Checked){result = CardApi.IdcrGetHMTInfoW(pRD, compatriot, photoPath, fpInfo);}else{result = CardApi.IdcrGetHMTInfoW(pRD, compatriot, photoPath, null);}if (0 == result){birthDate = ConvertDate(compatriot.birthDate, 1);validTerm = ConvertDate(compatriot.effectDate, 2);validTerm += '-';validTerm += ConvertDate(compatriot.expiryDate, 2);}}}if (result == 0){photo = Image.FromFile(photoPath);}ShowErrorDesc(result);Invalidate();}private void btnClose_Click(object sender, EventArgs e){if (pRD != IntPtr.Zero){CardApi.IdcrClose(pRD);pRD = IntPtr.Zero;}}protected override void OnHandleDestroyed(EventArgs e){base.OnHandleDestroyed(e);if (pRD != IntPtr.Zero){CardApi.IdcrClose(pRD);pRD = IntPtr.Zero;}CardApi.IdcrFinalize();if (photo != null){photo.Dispose();photo = null;}}void Clear(){cardType = 0;person.name = null;person.sexCode = null;person.sex = null;person.ethnicCode = null;person.ethnic = null;person.birthDate = null;person.address = null;person.idNumber = null;person.issuer = null;person.effectDate = null;person.expiryDate = null;person.appendInfo = null;foreigner.englishName = null;foreigner.sexCode = null;foreigner.sex = null;foreigner.prNumber = null;foreigner.countryCode = null;foreigner.country = null;foreigner.chineseName = null;foreigner.effectDate = null;foreigner.expiryDate = null;foreigner.birthDate = null;foreigner.version = null;foreigner.issuerCode = null;foreigner.issuer = null;compatriot.name = null;compatriot.sexCode = null;compatriot.sex = null;compatriot.birthDate = null;compatriot.address = null;compatriot.idNumber = null;compatriot.issuer = null;compatriot.effectDate = null;compatriot.expiryDate = null;compatriot.passNumber = null;compatriot.issueCount = null;fpInfo.fingerName1 = null;fpInfo.fingerName2 = null;birthDate = null;validTerm = null;if (photo != null){photo.Dispose();photo = null;}}string ConvertDate(string str, int mode){string year;string month;string day;if (1 == mode){if (str.Length >= 8){year = str.Substring(0, 4);month = str.Substring(4, 2);day = str.Substring(6, 2);return string.Format("{0}年{1}月{2}日", year, month, day);}}else{if (str.Equals("长期")){return "长期";}else{if (str.Length >= 8){year = str.Substring(0, 4);month = str.Substring(4, 2);day = str.Substring(6, 2);return string.Format("{0}.{1}.{2}", year, month, day);}}}return "";}}
}

JAVA

(1)必须使用32位JDK和JRE.
(2)依赖jar:  jna-4.5.0.jar和jna-platform-4.5.0.jar
(3)cardapi7.dll、sdtapi.dll、WltRS.dll、license.dat文件复制到生成的目录。(C盘和程序目录都要放)

生成的图片保存在当前用户临时目录中。Win7下为C:\Users\[用户名]\AppData\Local\Temp

注:JNA好像只能用绝对路径调用,部署时候需要自己指定下cardapi7.dll路径即可,我是直接放C盘根目录。

package com.shpte.idcard;import java.io.*;
import java.util.*;
import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.*;public class Card2{public static class PERSONINFOW extends Structure{public PERSONINFOW(){setAlignType(ALIGN_MSVC);}@Override  protected List<String> getFieldOrder(){return Arrays.asList(new String[] {"name","sexCode","sex","ethnicCode","ethnic","birthDate","address","idNumber","issuer","effectDate","expiryDate","appendInfo"});}public char[]name      =new char[16];public char[]sexCode   =new char[2];public char[]sex       =new char[2];public char[]ethnicCode=new char[4];public char[]ethnic    =new char[10];public char[]birthDate =new char[10];public char[]address   =new char[36];public char[]idNumber  =new char[20];public char[]issuer    =new char[16];public char[]effectDate=new char[10];public char[]expiryDate=new char[10];public char[]appendInfo=new char[36];}public static class FOREIGNERINFOW extends Structure{public FOREIGNERINFOW(){setAlignType(ALIGN_MSVC);}@Override  protected List<String> getFieldOrder(){return Arrays.asList(new String[] {"englishName","sexCode","sex","prNumber","countryCode","country","chineseName","effectDate","expiryDate","birthDate","version","issuerCode","issuer"});}public char[]englishName=new char[62];public char[]sexCode    =new char[2];public char[]sex        =new char[4];public char[]prNumber   =new char[16];public char[]countryCode=new char[4];public char[]country    =new char[20];public char[]chineseName=new char[16];public char[]effectDate =new char[10];public char[]expiryDate =new char[10];public char[]birthDate  =new char[10];public char[]version    =new char[4];public char[]issuerCode =new char[6];public char[]issuer     =new char[48];}public static class COMPATRIOTINFOW extends Structure{public COMPATRIOTINFOW(){setAlignType(ALIGN_MSVC);}@Override  protected List<String> getFieldOrder(){return Arrays.asList(new String[] {"name","sexCode","sex","birthDate","address","idNumber","issuer","effectDate","expiryDate","passNumber","issueCount"});}public char[]name      =new char[16];public char[]sexCode   =new char[2];public char[]sex       =new char[2];public char[]birthDate =new char[10];public char[]address   =new char[36];public char[]idNumber  =new char[20];public char[]issuer    =new char[16];public char[]effectDate=new char[10];public char[]expiryDate=new char[10];public char[]passNumber=new char[10];public char[]issueCount=new char[4];}public static class FPINFOW extends Structure{public FPINFOW(){setAlignType(ALIGN_MSVC);}@Override  protected List<String> getFieldOrder(){return Arrays.asList(new String[] {"fpData1","fpData2","fingerName1","fingerName2"});}public byte[]fpData1=new byte[512];public byte[]fpData2=new byte[512];public char[]fingerName1=new char[8];public char[]fingerName2=new char[8];}public interface CardApi extends StdCallLibrary{CardApi INSTANCE =(CardApi)Native.loadLibrary("cardapi7.dll",CardApi.class);public int IdcrInitialize(int dwFlags);public int IdcrOpen(IntByReference piPort, int dwBaudRate, int dwCmdIntv, int iBpPort, PointerByReference ppRD);public int IdcrFindCard(Pointer pRD);public int IdcrSelectCard(Pointer pRD);public int IdcrReadCard(Pointer pRD, int bReadFP, IntByReference piCardType);public int IdcrValidate(Pointer pRD, int bReadFP, IntByReference piCardType, int bRepeatRead);public int IdcrGetIDInfoW(Pointer pRD, PERSONINFOW pTextInfo, WString pszPhotoPath, FPINFOW pFPInfo);public int IdcrGetPRInfoW(Pointer pRD, FOREIGNERINFOW pTextInfo, WString pszPhotoPath, FPINFOW pFPInfo);public int IdcrGetHMTInfoW(Pointer pRD, COMPATRIOTINFOW pTextInfo, WString pszPhotoPath, FPINFOW pFPInfo);public void IdcrClose(Pointer pRD);public void IdcrFinalize();public void IdcrGetErrorDescW(char[]pszBuffer, int nBufLen, int nErrorCode);}public static String CStrToString(char[]str){int i=0;while(i<str.length && str[i]!=0){i++;}return new String(str,0,i);}public static void printError(String funcName, int result){char[]errorText=new char[32];CardApi.INSTANCE.IdcrGetErrorDescW(errorText,errorText.length,result);String str=String.format("%s Error:0x%X %s\n",funcName,result,CStrToString(errorText));System.out.println(str);}public static void main(String[]args) throws IOException{int ch;int result;IntByReference piPort=new IntByReference(0);PointerByReference ppRD=new PointerByReference();IntByReference piCardType=new IntByReference(0);Pointer pRD;int iCardType;PERSONINFOW person=new PERSONINFOW();FOREIGNERINFOW foreigner=new FOREIGNERINFOW();COMPATRIOTINFOW compatriot=new COMPATRIOTINFOW();FPINFOW fpInfo=new FPINFOW();String str=System.getProperty("java.io.tmpdir")+"photo.bmp";WString photoPath=new WString(str);result=CardApi.INSTANCE.IdcrInitialize(1);if(0!=result){printError("IdcrInitialize",result);return;}System.out.println("按Enter键打开端口");ch=System.in.read();System.in.read();result=CardApi.INSTANCE.IdcrOpen(piPort,115200,0,0,ppRD);if(0!=result){CardApi.INSTANCE.IdcrFinalize();printError("IdcrOpen",result);return;}pRD=ppRD.getValue();do{System.out.println("按'q'键退出,按Enter键读卡");ch=System.in.read();System.in.read();if(ch=='q'){break;}result=CardApi.INSTANCE.IdcrValidate(pRD, 1, piCardType, 1);if(0!=result){printError("IdcrValidate",result);continue;}iCardType=piCardType.getValue();if(1==iCardType){result=CardApi.INSTANCE.IdcrGetIDInfoW(pRD, person, photoPath, fpInfo);if(0==result){System.out.println(CStrToString(person.name));System.out.println(CStrToString(person.sex));System.out.println(CStrToString(person.ethnic));System.out.println(CStrToString(person.birthDate));System.out.println(CStrToString(person.address));System.out.println(CStrToString(person.idNumber));System.out.println(CStrToString(person.issuer));System.out.println(CStrToString(person.effectDate));System.out.println(CStrToString(person.expiryDate));System.out.println(CStrToString(fpInfo.fingerName1));System.out.println(CStrToString(fpInfo.fingerName2));}else{printError("IdcrGetIDInfoW",result);}}else if(2==iCardType){result=CardApi.INSTANCE.IdcrGetPRInfoW(pRD, foreigner, photoPath, fpInfo);if(0==result){System.out.println(CStrToString(foreigner.englishName));System.out.println(CStrToString(foreigner.sex));System.out.println(CStrToString(foreigner.prNumber));System.out.println(CStrToString(foreigner.country));System.out.println(CStrToString(foreigner.chineseName));System.out.println(CStrToString(foreigner.effectDate));System.out.println(CStrToString(foreigner.expiryDate));System.out.println(CStrToString(foreigner.birthDate));System.out.println(CStrToString(foreigner.issuer));System.out.println(CStrToString(fpInfo.fingerName1));System.out.println(CStrToString(fpInfo.fingerName2));}else{printError("IdcrGetPRInfoW",result);}}else if(3==iCardType){result=CardApi.INSTANCE.IdcrGetHMTInfoW(pRD, compatriot, photoPath, fpInfo);if(0==result){System.out.println(CStrToString(compatriot.name));System.out.println(CStrToString(compatriot.sex));System.out.println(CStrToString(compatriot.birthDate));System.out.println(CStrToString(compatriot.address));System.out.println(CStrToString(compatriot.idNumber));System.out.println(CStrToString(compatriot.issuer));System.out.println(CStrToString(compatriot.effectDate));System.out.println(CStrToString(compatriot.expiryDate));System.out.println(CStrToString(compatriot.passNumber));System.out.println(CStrToString(compatriot.issueCount));System.out.println(CStrToString(fpInfo.fingerName1));System.out.println(CStrToString(fpInfo.fingerName2));}else{printError("IdcrGetHMTInfoW",result);}}}while(true);CardApi.INSTANCE.IdcrClose(pRD);CardApi.INSTANCE.IdcrFinalize();}
}