需要用到dll和文件:

其中3个dll文件是需要调用的dll,license.dat文件为解压图片的授权文件

以下是需要用到的dll里面的方法:

  1. /************************端口类API *************************/
  2. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SetMaxRFByte", CharSet = CharSet.Ansi, SetLastError = true)]
  3. public static extern int Syn_SetMaxRFByte(int iPort, byte ucByte, int iIfOpen);
  4.  
  5. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_GetCOMBaud", CharSet = CharSet.Ansi, SetLastError = true)]
  6. public static extern int Syn_GetCOMBaud(int iPort, ref uint puiBaudRate);
  7.  
  8. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SetCOMBaud", CharSet = CharSet.Ansi, SetLastError = true)]
  9. public static extern int Syn_SetCOMBaud(int iPort, uint uiCurrBaud, uint uiSetBaud);
  10.  
  11. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_OpenPort", CharSet = CharSet.Ansi, SetLastError = true)]
  12. public static extern int Syn_OpenPort(int iPort);
  13.  
  14. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_ClosePort", CharSet = CharSet.Ansi, SetLastError = true)]
  15. public static extern int Syn_ClosePort(int iPort);
  16.  
  17. /**************************SAM类函数 **************************/
  18. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_ResetSAM", CharSet = CharSet.Ansi, SetLastError = true)]
  19. public static extern int Syn_ResetSAM(int iPort, int iIfOpen);
  20.  
  21. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_GetSAMStatus", CharSet = CharSet.Ansi, SetLastError = true)]
  22. public static extern int Syn_GetSAMStatus(int iPort, int iIfOpen);
  23.  
  24. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_GetSAMID", CharSet = CharSet.Ansi, SetLastError = true)]
  25. public static extern int Syn_GetSAMID(int iPort, ref byte pucSAMID, int iIfOpen);
  26.  
  27. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_GetSAMIDToStr", CharSet = CharSet.Ansi, SetLastError = true)]
  28. public static extern int Syn_GetSAMIDToStr(int iPort, ref byte pcSAMID, int iIfOpen);
  29.  
  30. /*************************身份证卡类函数 ***************************/
  31. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_StartFindIDCard", CharSet = CharSet.Ansi, SetLastError = true)]
  32. public static extern int Syn_StartFindIDCard(int iPort, ref byte pucIIN, int iIfOpen);
  33.  
  34. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SelectIDCard", CharSet = CharSet.Ansi, SetLastError = true)]
  35. public static extern int Syn_SelectIDCard(int iPort, ref byte pucSN, int iIfOpen);
  36.  
  37. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_ReadBaseMsg", CharSet = CharSet.Ansi, SetLastError = true)]
  38. public static extern int Syn_ReadBaseMsg(int iPort, IntPtr pucCHMsg, ref uint puiCHMsgLen, IntPtr pucPHMsg,
  39. ref uint puiPHMsgLen, int iIfOpen);
  40.  
  41. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_ReadIINSNDN", CharSet = CharSet.Ansi, SetLastError = true)]
  42. public static extern int Syn_ReadIINSNDN(int iPort, ref byte pucIINSNDN, int iIfOpen);
  43.  
  44. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_ReadBaseMsgToFile", CharSet = CharSet.Ansi,
  45. SetLastError = true)]
  46. public static extern int Syn_ReadBaseMsgToFile(int iPort, ref byte pcCHMsgFileName, ref uint puiCHMsgFileLen,
  47. ref byte pcPHMsgFileName, ref uint puiPHMsgFileLen, int iIfOpen);
  48.  
  49. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_ReadIINSNDNToASCII", CharSet = CharSet.Ansi,
  50. SetLastError = true)]
  51. public static extern int Syn_ReadIINSNDNToASCII(int iPort, ref byte pucIINSNDN, int iIfOpen);
  52.  
  53. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_ReadNewAppMsg", CharSet = CharSet.Ansi, SetLastError = true)]
  54. public static extern int Syn_ReadNewAppMsg(int iPort, ref byte pucAppMsg, ref uint puiAppMsgLen, int iIfOpen);
  55.  
  56. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_GetBmp", CharSet = CharSet.Ansi, SetLastError = true)]
  57. public static extern int Syn_GetBmp(string Wlt_File, int iPort);
  58.  
  59. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_ReadMsg", CharSet = CharSet.Ansi, SetLastError = true)]
  60. public static extern int Syn_ReadMsg(int iPortID, int iIfOpen, ref IDCardData pIDCardData);
  61.  
  62. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_FindReader", CharSet = CharSet.Ansi, SetLastError = true)]
  63. public static extern int Syn_FindReader();
  64.  
  65. /***********************设置附加功能函数 ************************/
  66. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SetPhotoPath", CharSet = CharSet.Ansi, SetLastError = true)]
  67. public static extern int Syn_SetPhotoPath(int iOption, ref byte cPhotoPath);
  68.  
  69. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SetPhotoType", CharSet = CharSet.Ansi, SetLastError = true)]
  70. public static extern int Syn_SetPhotoType(int iType);
  71.  
  72. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SetPhotoName", CharSet = CharSet.Ansi, SetLastError = true)]
  73. public static extern int Syn_SetPhotoName(int iType);
  74.  
  75. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SetSexType", CharSet = CharSet.Ansi, SetLastError = true)]
  76. public static extern int Syn_SetSexType(int iType);
  77.  
  78. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SetNationType", CharSet = CharSet.Ansi, SetLastError = true)]
  79. public static extern int Syn_SetNationType(int iType);
  80.  
  81. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SetBornType", CharSet = CharSet.Ansi, SetLastError = true)]
  82. public static extern int Syn_SetBornType(int iType);
  83.  
  84. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SetUserLifeBType", CharSet = CharSet.Ansi,
  85. SetLastError = true)]
  86. public static extern int Syn_SetUserLifeBType(int iType);
  87.  
  88. [DllImport("idCardDll\\SynIDCardAPI.dll", EntryPoint = "Syn_SetUserLifeEType", CharSet = CharSet.Ansi,
  89. SetLastError = true)]
  90. public static extern int Syn_SetUserLifeEType(int iType, int iOption);
  91.  
  92. [DllImport("idCardDll\\WltRS.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
  93. static extern int GetBmp(string pucPHMsg, int intf);

接口函数

读取身份证信息分两个阶段,第一个阶段是获取基本信息,第二个阶段是获取图片信息

获取基本信息很简单,直接调用dll的方法就可以完成,部分代码如下:

  1. int status = ;//默认为找不到身份证
  2. try
  3. {
  4. //先查找读卡器
  5. int i, nRet;
  6. i = Syn_FindReader();
  7. //只支持usb
  8. if (i > )
  9. {
  10. var nPort = i;
  11. if (Syn_OpenPort(nPort) == )
  12. {
  13. Thread.Sleep();
  14. if (Syn_SetMaxRFByte(nPort, , ) == )
  15. {
  16. Thread.Sleep();
  17. byte[] pucIIN = new byte[];
  18. byte[] pucSN = new byte[];
  19. IDCardData cardMsg = new IDCardData();
  20. nRet = Syn_StartFindIDCard(nPort, ref pucIIN[], ); //找卡
  21. nRet = Syn_SelectIDCard(nPort, ref pucSN[], ); //选卡
  22. string cardStr = new string(' ', ); //身份证基本信息返回长度为256
  23. string imgMsg = new string(' ', ); //身份证图片信息返回长度为1024
  24. IntPtr msg = Marshal.StringToHGlobalAnsi(cardStr); //身份证基本信息
  25. IntPtr img = Marshal.StringToHGlobalAnsi(imgMsg); //身份证图片
  26. uint mLen = ;
  27. uint iLen = ;
  28. nRet = Syn_ReadBaseMsg(nPort, msg, ref mLen, img, ref iLen, );
  29. if (nRet == )
  30. {
  31. Syn_ClosePort(nPort);
  32. string card = Marshal.PtrToStringUni(msg);
  33. char[] cartb = card.ToCharArray();
  34. cardMsg.Name = (new string(cartb, , )).Trim();
  35. cardMsg.Sex = new string(cartb, , );
  36. cardMsg.Nation = new string(cartb, , );
  37. cardMsg.Born = new string(cartb, , );
  38. cardMsg.Address = (new string(cartb, , )).Trim();
  39. cardMsg.IDCardNo = new string(cartb, , );
  40. cardMsg.GrantDept = (new string(cartb, , )).Trim();
  41. cardMsg.UserLifeBegin = new string(cartb, , );
  42. cardMsg.UserLifeEnd = new string(cartb, , );

获取基本信息

获取图片方法有点麻烦,首先通过Syn_ReadBaseMsg方法返回的图片指针和长度获取的字节信息:

  1. byte[] data=new byte[iLen];
  2. Marshal.Copy(img,data,,data.Length);

将这个获取到的字节信息保存为文件,注意,这里的文件不是图片文件,而是一个wlt类型文件,如果需要获取图片,那么还需要通过GetBmp方法做转换

  1. private static string GetImageBase64Str(byte[] data, string idCardNo)
  2. {
  3. if (!CheckLicense()) return string.Empty;//license.dat文件失败,那么就不能去获取文件
  4. var wltFileName = Path.Combine(_imageDirPath,
  5. string.Format("{0}.wlt", idCardNo));
  6. if (File.Exists(wltFileName))
  7. {
  8. File.Delete(wltFileName);
  9. }
  10. using (FileStream fs = new FileStream(wltFileName, FileMode.Create))
  11. {
  12. fs.Write(data, , data.Length);
  13. fs.Close();
  14. }
  15. var nRet = GetBmp(wltFileName, );
  16. if (nRet == )
  17. {
  18. // Thread.Sleep(200);
  19. string bmpFileName = Path.Combine(_imageDirPath,
  20. string.Format("{0}.bmp", idCardNo));
  21. if (File.Exists(bmpFileName))
  22. {
  23. var str = GetFileBase64Str(bmpFileName);
  24. // File.Delete(bmpFileName);
  25. return str;
  26. }
  27. }
  28. return string.Empty;
  29. }

代码中将图片信息转换为了base64字符串。

注意:

  1.由于GetBmp调用了sdtapi.dll中的方法,所以在之前要先要关闭读取的端口,不然会报错。(这是网上用户提醒的,我没有测试过不关闭的情况)

  2.GetBmp方法会在wlt文件的当前目录下生成一个同名的bmp文件,这个文件就是身份证图片文件

  3.获取图片方法需要厂家的授权文件,我用的dll和授权文件都是新中新的,其中授权文件为license.dat,这个文件必须存放在C盘根目录下,并且不能改名,不然读取会出错

  1. //检测授权文件
  2. private static bool CheckLicense()
  3. {
  4. var licenceFile = @"c:\license.dat";
  5. var localFile = @"idCardDll\license.dat";
  6. try
  7. {
  8. if (!File.Exists(licenceFile))
  9. {
  10. //不存在,拷贝文件过去
  11. File.Copy(localFile,licenceFile,true);
  12. return true;
  13. }
  14. //文件存在,需要判断数据是否一致
  15. string local = string.Empty;
  16. string license = string.Empty;
  17. using (FileStream fs = new FileStream(localFile, FileMode.Open, FileAccess.Read))
  18. {
  19. using (StreamReader sr = new StreamReader(fs))
  20. {
  21. local = sr.ReadToEnd();
  22. }
  23. }
  24. using (FileStream fs = new FileStream(licenceFile, FileMode.Open, FileAccess.Read))
  25. {
  26. using (StreamReader sr = new StreamReader(fs))
  27. {
  28. license = sr.ReadToEnd();
  29. }
  30. }
  31. if (local == license)
  32. {
  33. return true;
  34. }
  35. else
  36. {
  37. File.Copy(localFile, licenceFile, true);
  38. return true;
  39. }
  40. }
  41. catch (Exception ex)
  42. {
  43. //"判断license失败,不能去获取图片";
  44. return false;
  45. }
  46.  
  47. }

拷贝检测授权文件

在转换图片之前先判断授权文件,成功在执行转换操作。

最终结果是将信息存储IDCardData结构体中,图片信息转换为base64str。

  1. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = )]
  2. public struct IDCardData
  3. {
  4. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
  5. public string Name; //姓名
  6. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
  7. public string Sex; //性别
  8. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
  9. public string Nation; //名族
  10. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
  11. public string Born; //出生日期
  12. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
  13. public string Address; //住址
  14. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
  15. public string IDCardNo; //身份证号
  16. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
  17. public string GrantDept; //发证机关
  18.  
  19. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
  20. public string UserLifeBegin; // 有效开始日期
  21.  
  22. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
  23. public string UserLifeEnd; // 有效截止日期
  24.  
  25. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
  26. public string reserved; // 保留
  27. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
  28. public string PhotoBase64Str; // 照片路径
  29. }

身份证结构

WltRS.dll一定要新一点的,我以前用的是2007年的,在转换头像的时候总是报错,找了一个新的,是2012年的,就好了。

以下是我写的一个demo,可以直接调用获取,包含了32位和64的驱动

https://gitee.com/sczmzx/IdCardReaderHelper/tree/master/IdCardReaderHelper

c# 新中新二代身份证阅读,包含头像,支持华视的更多相关文章

  1. 关于新中新二代身份证读卡器DKQ-A16D的一些问题

    今天拿到了新中新DKQ-A16D,随机光盘里有以下文件: 我遇到的问题是,如果直接打开\二代征SDK开发包\DLL\测试程序\C#_2008\WindowsFormsApplication1\目录下的 ...

  2. 用Python在Linux下调用新中新DKQ-A16D读卡器,读二代证数据

    1.背景 最近在研究二代证读卡器,手头上的设备是新中新DKQ-A16D,在官网(https://www.onecardok.com.cn/download)逛了一圈,发现Win下的示例,浏览器插件很多 ...

  3. 用Go语言在Linux下调用新中新DKQ-A16D读卡器,读二代证数据

    1.背景 前几天用Python在Linux下成功的获取了二代证数据,最近正在学Go语言,这两天想着用Go语言也实现一下试看看. 2.开搞C++ 这次就比较简单了,直接把CppDemo里面的SynRea ...

  4. 二代身份证阅读器(XZX)

    问题一 解决方法: 通常我把所有的dll复制到system32文件夹,64位系统复制到sysWOW64文件夹,而且编译选项CPU要选择X86 问题二 解决方法: 图片路径默认是C:\,对C:\没有写的 ...

  5. Linux 4.21包含对AMD Rome处理器中新的Zen 2架构重要的新优化

    导读 Phoronix的Linux爱好者报告说,Linux 4.21里包含对AMD Rome处理器中新的Zen 2架构重要的新优化.AMD新推出的7nm EPYC Rome芯片带来了一种全新的独特架构 ...

  6. HTML5中新的结构元素

    HTML5中新的结构元素 1. HTML5初始文件 1.1.doctype 在之前,doctype的声明是这样的: "http://www.w3. org/TR/html4/strict.d ...

  7. HTML5中新添加事件

    HTML5中新添加了很多事件,但是由于他们的兼容问题不是很理想,应用实战性不是太强,所以在这里基本省略,咱们只分享应用广泛兼容不错的事件,日后随着兼容情况提升以后再陆续添加分享.今天为大家介绍的事件主 ...

  8. CSS3中新出现的技术

    CSS3中新出现的技术 CSS媒体查询 媒体查询 包含了一个媒体类型和至少一个使用如宽度.高度和颜色等媒体属性来限制样式表范围的表达式.CSS3加入的媒体查询使得无需修改内容便可以使样式应用于某些特定 ...

  9. 是否以某字符串结尾 是否以某字符串开始 是否是整数 裁减字符串空格 是否是浮点数 是否所有字符为数字类型 是否为空 是否是EMAIL 是否是电话号码 身份证号码验证-支持新的带x身份证 日期验证

    /* 1.是否以某字符串结尾 endsWith(theStr,endStr) @param theStr:要判断的字符串 @param endStr:以此字符串结尾 @return boolean; ...

随机推荐

  1. 条款35:考虑virtual函数以外的其他选择

    有一部分人总是主张virtual函数几乎总应该是private:例如下面这个例子,例子时候游戏,游戏里面的任务都拥有健康值这一属性: class GameCharacter{ public: int ...

  2. 进程、线程、ThreadLlocal

    1.线程是最小的执行单位,而进程中至少一个线程组:如果调度进程和线程,完全由操作系统决定,程序自己不能决定什么时候执行,执行多长时间 Unix/Linux操作系统提供了一个fork()系统调用,它非常 ...

  3. Git中从远程的分支获取最新的版本到本地方式

    Git中从远程的分支获取最新的版本到本地方式如下, 如何更新下载到代码到本地,请参阅ice的博客基于Github参与eoe的开源项目指南 方式一 . 查看远程仓库 $ git remote -v eo ...

  4. 使用jsonp跨域调用百度js实现搜索框智能提示(转)

    http://www.cnblogs.com/oppoic/p/baidu_auto_complete.html 项目中常常用到搜索,特别是导航类的网站.自己做关键字搜索不太现实,直接调用百度的是最好 ...

  5. WPF中ItemsControl绑定到Google ProtocolBuffer的结构体时的性能问题

    背景: 最近遇到一个DataGrid的性能问题:里面大概有4000个数据, 绑定的ItemSource的类也只有一层数据,即简单的List(里面每个是Protocol Buffer自动产生的一个类,1 ...

  6. centos6.5 安装gcc 4.9.0

    wget http://gcc.skazkaforyou.com/releases/gcc-4.9.0/gcc-4.9.0.tar.gz  // 下载源码 tar -zxvf gcc-4.9.0 cd ...

  7. Python学习笔记 - MySql的使用

    一.安装MySql模块 Python2.X pip install MySQLdb Python3.X pip install pymysql 二.数据库连接接口 由于Python统一了数据库连接的接 ...

  8. 反射ORM 三层(for oracle)

    sql server and oracle 不同之处只在于: 1·参数@和: 2·自增和序列 3·oracle使用了存储过程以获得当前插入数据的ID DAL层的ORM using Oracle.Dat ...

  9. 蓝桥杯 基础训练 BASIC-27 2n皇后问题

    基础练习 2n皇后问题   时间限制:1.0s   内存限制:512.0MB 问题描述 给定一个n*n的棋盘,棋盘中有一些位置不能放皇后.现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都 ...

  10. Java基础--ThreadLocal

    Java中的ThreadLocal 可以看做以线程标识为key的Map,在多线程开发中使用非常方便. 示例 class ThreadEnv { // 用匿名内部类覆盖ThreadLocal的initi ...