c# 新中新二代身份证阅读,包含头像,支持华视
需要用到dll和文件:

其中3个dll文件是需要调用的dll,license.dat文件为解压图片的授权文件
以下是需要用到的dll里面的方法:
/************************端口类API *************************/
[DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SetMaxRFByte", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_SetMaxRFByte(int iPort, byte ucByte, int iIfOpen); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_GetCOMBaud", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_GetCOMBaud(int iPort, ref uint puiBaudRate); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SetCOMBaud", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_SetCOMBaud(int iPort, uint uiCurrBaud, uint uiSetBaud); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_OpenPort", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_OpenPort(int iPort); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_ClosePort", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_ClosePort(int iPort); /**************************SAM类函数 **************************/
[DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_ResetSAM", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_ResetSAM(int iPort, int iIfOpen); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_GetSAMStatus", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_GetSAMStatus(int iPort, int iIfOpen); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_GetSAMID", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_GetSAMID(int iPort, ref byte pucSAMID, int iIfOpen); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_GetSAMIDToStr", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_GetSAMIDToStr(int iPort, ref byte pcSAMID, int iIfOpen); /*************************身份证卡类函数 ***************************/
[DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_StartFindIDCard", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_StartFindIDCard(int iPort, ref byte pucIIN, int iIfOpen); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SelectIDCard", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_SelectIDCard(int iPort, ref byte pucSN, int iIfOpen); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_ReadBaseMsg", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_ReadBaseMsg(int iPort, IntPtr pucCHMsg, ref uint puiCHMsgLen, IntPtr pucPHMsg,
ref uint puiPHMsgLen, int iIfOpen); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_ReadIINSNDN", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_ReadIINSNDN(int iPort, ref byte pucIINSNDN, int iIfOpen); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_ReadBaseMsgToFile", CharSet = CharSet.Ansi,
SetLastError = true)]
public static extern int Syn_ReadBaseMsgToFile(int iPort, ref byte pcCHMsgFileName, ref uint puiCHMsgFileLen,
ref byte pcPHMsgFileName, ref uint puiPHMsgFileLen, int iIfOpen); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_ReadIINSNDNToASCII", CharSet = CharSet.Ansi,
SetLastError = true)]
public static extern int Syn_ReadIINSNDNToASCII(int iPort, ref byte pucIINSNDN, int iIfOpen); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_ReadNewAppMsg", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_ReadNewAppMsg(int iPort, ref byte pucAppMsg, ref uint puiAppMsgLen, int iIfOpen); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_GetBmp", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_GetBmp(string Wlt_File, int iPort); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_ReadMsg", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_ReadMsg(int iPortID, int iIfOpen, ref IDCardData pIDCardData); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_FindReader", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_FindReader(); /***********************设置附加功能函数 ************************/
[DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SetPhotoPath", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_SetPhotoPath(int iOption, ref byte cPhotoPath); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SetPhotoType", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_SetPhotoType(int iType); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SetPhotoName", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_SetPhotoName(int iType); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SetSexType", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_SetSexType(int iType); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SetNationType", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_SetNationType(int iType); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SetBornType", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern int Syn_SetBornType(int iType); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SetUserLifeBType", CharSet = CharSet.Ansi,
SetLastError = true)]
public static extern int Syn_SetUserLifeBType(int iType); [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SetUserLifeEType", CharSet = CharSet.Ansi,
SetLastError = true)]
public static extern int Syn_SetUserLifeEType(int iType, int iOption); [DllImport("idCardDll\\WltRS.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
static extern int GetBmp(string pucPHMsg, int intf);
接口函数
读取身份证信息分两个阶段,第一个阶段是获取基本信息,第二个阶段是获取图片信息
获取基本信息很简单,直接调用dll的方法就可以完成,部分代码如下:
int status = ;//默认为找不到身份证
try
{
//先查找读卡器
int i, nRet;
i = Syn_FindReader();
//只支持usb
if (i > )
{
var nPort = i;
if (Syn_OpenPort(nPort) == )
{
Thread.Sleep();
if (Syn_SetMaxRFByte(nPort, , ) == )
{
Thread.Sleep();
byte[] pucIIN = new byte[];
byte[] pucSN = new byte[];
IDCardData cardMsg = new IDCardData();
nRet = Syn_StartFindIDCard(nPort, ref pucIIN[], ); //找卡
nRet = Syn_SelectIDCard(nPort, ref pucSN[], ); //选卡
string cardStr = new string(' ', ); //身份证基本信息返回长度为256
string imgMsg = new string(' ', ); //身份证图片信息返回长度为1024
IntPtr msg = Marshal.StringToHGlobalAnsi(cardStr); //身份证基本信息
IntPtr img = Marshal.StringToHGlobalAnsi(imgMsg); //身份证图片
uint mLen = ;
uint iLen = ;
nRet = Syn_ReadBaseMsg(nPort, msg, ref mLen, img, ref iLen, );
if (nRet == )
{
Syn_ClosePort(nPort);
string card = Marshal.PtrToStringUni(msg);
char[] cartb = card.ToCharArray();
cardMsg.Name = (new string(cartb, , )).Trim();
cardMsg.Sex = new string(cartb, , );
cardMsg.Nation = new string(cartb, , );
cardMsg.Born = new string(cartb, , );
cardMsg.Address = (new string(cartb, , )).Trim();
cardMsg.IDCardNo = new string(cartb, , );
cardMsg.GrantDept = (new string(cartb, , )).Trim();
cardMsg.UserLifeBegin = new string(cartb, , );
cardMsg.UserLifeEnd = new string(cartb, , );
获取基本信息
获取图片方法有点麻烦,首先通过Syn_ReadBaseMsg方法返回的图片指针和长度获取的字节信息:
byte[] data=new byte[iLen];
Marshal.Copy(img,data,,data.Length);
将这个获取到的字节信息保存为文件,注意,这里的文件不是图片文件,而是一个wlt类型文件,如果需要获取图片,那么还需要通过GetBmp方法做转换
private static string GetImageBase64Str(byte[] data, string idCardNo)
{
if (!CheckLicense()) return string.Empty;//license.dat文件失败,那么就不能去获取文件
var wltFileName = Path.Combine(_imageDirPath,
string.Format("{0}.wlt", idCardNo));
if (File.Exists(wltFileName))
{
File.Delete(wltFileName);
}
using (FileStream fs = new FileStream(wltFileName, FileMode.Create))
{
fs.Write(data, , data.Length);
fs.Close();
}
var nRet = GetBmp(wltFileName, );
if (nRet == )
{
// Thread.Sleep(200);
string bmpFileName = Path.Combine(_imageDirPath,
string.Format("{0}.bmp", idCardNo));
if (File.Exists(bmpFileName))
{
var str = GetFileBase64Str(bmpFileName);
// File.Delete(bmpFileName);
return str;
}
}
return string.Empty;
}
代码中将图片信息转换为了base64字符串。
注意:
1.由于GetBmp调用了sdtapi.dll中的方法,所以在之前要先要关闭读取的端口,不然会报错。(这是网上用户提醒的,我没有测试过不关闭的情况)
2.GetBmp方法会在wlt文件的当前目录下生成一个同名的bmp文件,这个文件就是身份证图片文件
3.获取图片方法需要厂家的授权文件,我用的dll和授权文件都是新中新的,其中授权文件为license.dat,这个文件必须存放在C盘根目录下,并且不能改名,不然读取会出错
//检测授权文件
private static bool CheckLicense()
{
var licenceFile = @"c:\license.dat";
var localFile = @"idCardDll\license.dat";
try
{
if (!File.Exists(licenceFile))
{
//不存在,拷贝文件过去
File.Copy(localFile,licenceFile,true);
return true;
}
//文件存在,需要判断数据是否一致
string local = string.Empty;
string license = string.Empty;
using (FileStream fs = new FileStream(localFile, FileMode.Open, FileAccess.Read))
{
using (StreamReader sr = new StreamReader(fs))
{
local = sr.ReadToEnd();
}
}
using (FileStream fs = new FileStream(licenceFile, FileMode.Open, FileAccess.Read))
{
using (StreamReader sr = new StreamReader(fs))
{
license = sr.ReadToEnd();
}
}
if (local == license)
{
return true;
}
else
{
File.Copy(localFile, licenceFile, true);
return true;
}
}
catch (Exception ex)
{
//"判断license失败,不能去获取图片";
return false;
} }
拷贝检测授权文件
在转换图片之前先判断授权文件,成功在执行转换操作。
最终结果是将信息存储IDCardData结构体中,图片信息转换为base64str。
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = )]
public struct IDCardData
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
public string Name; //姓名
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
public string Sex; //性别
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
public string Nation; //名族
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
public string Born; //出生日期
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
public string Address; //住址
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
public string IDCardNo; //身份证号
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
public string GrantDept; //发证机关 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
public string UserLifeBegin; // 有效开始日期 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
public string UserLifeEnd; // 有效截止日期 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
public string reserved; // 保留
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
public string PhotoBase64Str; // 照片路径
}
身份证结构
WltRS.dll一定要新一点的,我以前用的是2007年的,在转换头像的时候总是报错,找了一个新的,是2012年的,就好了。
以下是我写的一个demo,可以直接调用获取,包含了32位和64的驱动
https://gitee.com/sczmzx/IdCardReaderHelper/tree/master/IdCardReaderHelper
c# 新中新二代身份证阅读,包含头像,支持华视的更多相关文章
- 关于新中新二代身份证读卡器DKQ-A16D的一些问题
今天拿到了新中新DKQ-A16D,随机光盘里有以下文件: 我遇到的问题是,如果直接打开\二代征SDK开发包\DLL\测试程序\C#_2008\WindowsFormsApplication1\目录下的 ...
- 用Python在Linux下调用新中新DKQ-A16D读卡器,读二代证数据
1.背景 最近在研究二代证读卡器,手头上的设备是新中新DKQ-A16D,在官网(https://www.onecardok.com.cn/download)逛了一圈,发现Win下的示例,浏览器插件很多 ...
- 用Go语言在Linux下调用新中新DKQ-A16D读卡器,读二代证数据
1.背景 前几天用Python在Linux下成功的获取了二代证数据,最近正在学Go语言,这两天想着用Go语言也实现一下试看看. 2.开搞C++ 这次就比较简单了,直接把CppDemo里面的SynRea ...
- 二代身份证阅读器(XZX)
问题一 解决方法: 通常我把所有的dll复制到system32文件夹,64位系统复制到sysWOW64文件夹,而且编译选项CPU要选择X86 问题二 解决方法: 图片路径默认是C:\,对C:\没有写的 ...
- Linux 4.21包含对AMD Rome处理器中新的Zen 2架构重要的新优化
导读 Phoronix的Linux爱好者报告说,Linux 4.21里包含对AMD Rome处理器中新的Zen 2架构重要的新优化.AMD新推出的7nm EPYC Rome芯片带来了一种全新的独特架构 ...
- HTML5中新的结构元素
HTML5中新的结构元素 1. HTML5初始文件 1.1.doctype 在之前,doctype的声明是这样的: "http://www.w3. org/TR/html4/strict.d ...
- HTML5中新添加事件
HTML5中新添加了很多事件,但是由于他们的兼容问题不是很理想,应用实战性不是太强,所以在这里基本省略,咱们只分享应用广泛兼容不错的事件,日后随着兼容情况提升以后再陆续添加分享.今天为大家介绍的事件主 ...
- CSS3中新出现的技术
CSS3中新出现的技术 CSS媒体查询 媒体查询 包含了一个媒体类型和至少一个使用如宽度.高度和颜色等媒体属性来限制样式表范围的表达式.CSS3加入的媒体查询使得无需修改内容便可以使样式应用于某些特定 ...
- 是否以某字符串结尾 是否以某字符串开始 是否是整数 裁减字符串空格 是否是浮点数 是否所有字符为数字类型 是否为空 是否是EMAIL 是否是电话号码 身份证号码验证-支持新的带x身份证 日期验证
/* 1.是否以某字符串结尾 endsWith(theStr,endStr) @param theStr:要判断的字符串 @param endStr:以此字符串结尾 @return boolean; ...
随机推荐
- window上脚本到linux上不能用
window上的脚本一定要用dos2unix 文件名处理一下
- eclipse部署和启动guns
eclipse部署guns: 1.import -> 搜索maven -> Existing Maven Projects -> 选择guns根目录 2.修改配置文件: spring ...
- 安装Babel(命令行环境,针对Babel6.x版本)
1.首先安装babel-cli(用于在终端使用babel) npm install -g babel-cli 2.然后安装babel-preset-es2015插件 npm install --sav ...
- mobiscroll时间控件
https://docs.mobiscroll.com/3-0-0_beta/javascript/numpad#events 这个是官方的日期插件,日历,什么效果都有,很强大的. mobiscrol ...
- db2生成连续日期
//生成时间段内连续日期 select * from ( select date('2008-01-01') + (row_NUMBER() over () -1) days AS datennn f ...
- 高可用-软件heartbeat的入门介绍
注:参考互联网整理. 一.简介Linux-HA的全称是High-Availability Linux,它是一个开源项目,这个开源项目的目标是:通过社区开发者的共同努力,提供一个增强linux可靠性(r ...
- Java VM(虚拟机) 参数
-XX:PermSize/-XX:MaxPermSize,永久代内存: 1. 虚拟机参数:-ea,支持 assert 断言关键字 eclipse 默认是不开启此参数的,也就是虽然编译器支持 asser ...
- inndb索引原理
###详解b+树如上图,是一颗b+树,关于b+树的定义可以参见B+树,这里只说一些重点,浅蓝色的块我们称之为一个磁盘块,可以看到每个磁盘块包含几个数据项(深蓝色所示)和指针(黄色所示),如磁盘块1包含 ...
- Centos 7 安装 Python3.7
目录 下载Python Python安装 遇到问题 错误: configure: error: no acceptable C compiler found in $PATH 错误: can't de ...
- Til the Cows Come Home (最短路模板题)
个人心得:模板题,不过还是找到了很多问题,真的是头痛,为什么用dijkstra算法book[1]=1就错了..... 纠结中.... Bessie is out in the field and wa ...