Newer
Older
ICS / ICS / CardReader.cs
using ICS.model;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace ICS
{
    class CardReader
    {
        public static bool cardReaderInited = false;
        public static bool cardReaderInited2 = false;
        public static log4net.ILog log = log4net.LogManager.GetLogger("ICS");
        // 身份证读卡
        [DllImport("sdtapi.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_OpenPort(int iPort);
        [DllImport("sdtapi.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern int SDT_ClosePort(int iPort);
        [DllImport("sdtapi.dll", CallingConvention = CallingConvention.StdCall)]
        static extern int SDT_StartFindIDCard(int iPort, byte[] pucManaInfo, int iIfOpen);
        [DllImport("sdtapi.dll", CallingConvention = CallingConvention.StdCall)]
        static extern int SDT_SelectIDCard(int iPort, byte[] pucManaMsg, int iIfOpen);
        [DllImport("sdtapi.dll", CallingConvention = CallingConvention.StdCall)]
        static extern int SDT_ReadBaseMsg(int iPort, byte[] pucCHMsg, ref UInt32 puiCHMsgLen, byte[] pucPHMsg, ref UInt32 puiPHMsgLen, int iIfOpen);
        [DllImport("WltRS.dll", CallingConvention = CallingConvention.StdCall)]
        static extern int GetBmp(string Wlt_File, int intf);
               

        //白色读卡器
        public static string readCardInfo()
        {
            string result = "";
            CardInfo cardInfo = null;
            int iPort = 1001;
            try
            {
                //身份证读卡器初始化
                //if (cardReaderInited == false)
                {
                    int iRet = -1; ;
                    
                    iRet = SDT_OpenPort(iPort);
                    if (iRet != 0x90)
                    {
                        MessageBox.Show("身份证读卡器初始化失败!", "提示");
                        SDT_ClosePort(iPort);
                        return "";
                    }
                    else
                    {
                        cardReaderInited = true;
                    }
                }
                
                    byte[] CardPUCIIN = new byte[255];
                    byte[] pucManaMsg = new byte[255];
                    byte[] pucCHMsg = new byte[255];
                    byte[] pucPHMsg = new byte[3024];
                    UInt32 puiCHMsgLen = 0;
                    UInt32 puiPHMsgLen = 0;
                    int st = 0;
                    st = SDT_StartFindIDCard(1001, CardPUCIIN, 1);
                    Thread.Sleep(200);
                    if (st == 0x9f)
                    {
                        st = SDT_SelectIDCard(1001, pucManaMsg, 1);
                        if (st == 0x90)
                        {
                            st = SDT_ReadBaseMsg(1001, pucCHMsg, ref puiCHMsgLen, pucPHMsg, ref puiPHMsgLen, 1);
                            if (st == 0x90)
                            {
                                cardInfo = new CardInfo();
                                cardInfo.Name = ASCIIEncoding.Unicode.GetString(pucCHMsg, 0, 30).Trim();
                                cardInfo.Sex = ASCIIEncoding.Unicode.GetString(pucCHMsg, 30, 2).Trim();                                
                                cardInfo.Birthday = ASCIIEncoding.Unicode.GetString(pucCHMsg, 36, 16).Trim();
                                cardInfo.Address = ASCIIEncoding.Unicode.GetString(pucCHMsg, 52, 70).Trim();
                                cardInfo.IdCardNo = ASCIIEncoding.Unicode.GetString(pucCHMsg, 122, 36).Trim();
                                cardInfo.Authority = ASCIIEncoding.Unicode.GetString(pucCHMsg, 158, 30).Trim();
                                cardInfo.StartTime = ASCIIEncoding.Unicode.GetString(pucCHMsg, 188, 16).Trim();
                                cardInfo.EndTime = ASCIIEncoding.Unicode.GetString(pucCHMsg, 204, 16).Trim();

                                //民族
                                cardInfo.Nation = Enum.GetName(typeof(nation), Convert.ToInt16(ASCIIEncoding.Unicode.GetString(pucCHMsg, 32, 4).Trim()));

                                string path0 = Application.StartupPath + "\\" + DateTime.Now.ToString("yyyyMMddhhmmss");
                                string path = path0 + ".wlt";
                                File.Delete(path);

                                FileStream fs = File.Open(path, FileMode.Append);
                                fs.Write(pucPHMsg, 0, (int)puiPHMsgLen);
                                fs.Close();

                                int img = GetBmp(path, 2);
                                string faceImageLoadPath = path0 + ".bmp";
                                // string faceImageLoadPath = Application.StartupPath + "\\TEMP"; // 将身份证的照片存入TEMP目录
                                ImageFormat faceImageLoadFormat = ImageFormat.Bmp;

                                // Image ph =Image.FromFile(faceImageLoadPath);
                                // ph.Save(ms, ImageFormat.Bmp);
                                // byte[] arr = ms.ToArray();
                                Bitmap bmpImg = new Bitmap(faceImageLoadPath);
                                
                                MemoryStream ms = new MemoryStream();
                                bmpImg.Save(ms, ImageFormat.Bmp);
                                
                                byte[] arr = new byte[ms.Length];
                                ms.Position = 0;
                                ms.Read(arr, 0, (int)ms.Length);
                                ms.Close();

                                cardInfo.Photo = "data:image/bmp;base64," + Convert.ToBase64String(arr);
                                File.Delete(faceImageLoadPath);
                            }
                        }
                    }
                    else
                    {
                        MessageBox.Show("读卡失败,请检查卡片放置位置。");
                    }
               
            }
            catch (Exception ex)
            {
                log.Info("读取身份证出错:" + ex.Message);
            }
            finally
            {
                if (cardInfo != null)
                {
                   result = JsonConvert.SerializeObject(cardInfo);
                }
                SDT_ClosePort(iPort);
            }
            return result;
        }

        //黑色读卡器
        public static int Port = 0;
        public const int cbDataSize = 128;
        public static Boolean IsConnected = false;

        [DllImport("termb.dll")]
        static extern int InitCommExt();//自动搜索身份证阅读器并连接身份证阅读器 
        [DllImport("termb.dll")]
        static extern int CloseComm();//断开与身份证阅读器连接 
        [DllImport("termb.dll")]
        static extern int Authenticate();//判断是否有放卡,且是否身份证 
        [DllImport("termb.dll")]
        public static extern int Read_Content(int index);//读卡操作,信息文件存储在dll所在下
        [DllImport("termb.dll")]
        public static extern int ReadContent(int index);//读卡操作,信息文件存储在dll所在下
        [DllImport("termb.dll")]
        static extern int GetSAMID(StringBuilder SAMID);//获取SAM模块编号
        [DllImport("termb.dll")]
        static extern int getName(StringBuilder data, int cbData);//获取姓名
        [DllImport("termb.dll")]
        static extern int getSex(StringBuilder data, int cbData);//获取性别
        [DllImport("termb.dll")]
        static extern int getNation(StringBuilder data, int cbData);//获取民族
        [DllImport("termb.dll")]
        static extern int getBirthdate(StringBuilder data, int cbData);//获取生日(YYYYMMDD)
        [DllImport("termb.dll")]
        static extern int getAddress(StringBuilder data, int cbData);//获取地址
        [DllImport("termb.dll")]
        static extern int getIDNum(StringBuilder data, int cbData);//获取身份证号
        [DllImport("termb.dll")]
        static extern int getIssue(StringBuilder data, int cbData);//获取签发机关
        [DllImport("termb.dll")]
        static extern int getEffectedDate(StringBuilder data, int cbData);//获取有效期起始日期(YYYYMMDD)
        [DllImport("termb.dll")]
        static extern int getExpiredDate(StringBuilder data, int cbData);//获取有效期截止日期(YYYYMMDD) 
        [DllImport("termb.dll")]
        static extern int GetBmpPhotoExt();//解析身份证照片
        [DllImport("termb.dll")]
        static extern int getBMPPhotoBase64(StringBuilder data, int cbData);//获取BMP头像Base64编码 
        [DllImport("termb.dll")]
        static extern int GetBmpPhoto(string PhotoPath);//解析身份证照片




        public static string readCardInfo2()
        {
            string result = "";
            CardInfo cardInfo = null;
            
            try
            {
                //身份证读卡器初始化
                //if (cardReaderInited2 == false)
                {
                    int AutoSearchReader = InitCommExt();
                    if (AutoSearchReader > 0)
                    {
                        Port = AutoSearchReader;
                        IsConnected = true; 
                        StringBuilder sb = new StringBuilder(cbDataSize);
                        GetSAMID(sb);
                        cardReaderInited2 = true;
                        //MessageBox.Show("连接身份证阅读器成功,SAM模块编号:" + sb);                         
                    }
                    else
                    {
                        MessageBox.Show("检查是否正确连接设备");
                        return "";
                    }
                }
                //else
                {
                    //卡认证
                    int FindCard = Authenticate();
                    if (FindCard != 1)
                    {
                        MessageBox.Show("请放置身份证");
                        return "";
                    }
                    //读卡
                    int rs = Read_Content(1);
                    if (rs != 1 && rs != 2 && rs != 3)
                    {
                        MessageBox.Show("读卡失败");
                        return "";
                    }

                    //读卡成功
                    cardInfo = new CardInfo();

                    //姓名
                    StringBuilder sb = new StringBuilder(cbDataSize);
                    getName(sb, cbDataSize);
                    cardInfo.Name = sb.ToString();

                    //民族/国家
                    getNation(sb, cbDataSize);
                    cardInfo.Nation = sb.ToString();

                    //性别 
                    getSex(sb, cbDataSize);
                    cardInfo.Sex = sb.ToString();

                    //出生 
                    getBirthdate(sb, cbDataSize);
                    cardInfo.Birthday = sb.ToString();
                    // sb.ToString().Substring(0, 4) - sb.ToString().Substring(4, 2) - sb.ToString().Substring(6, 2);

                    //地址 
                    getAddress(sb, cbDataSize);
                    cardInfo.Address = sb.ToString();
                     

                    //号码 
                    getIDNum(sb, cbDataSize);
                    cardInfo.IdCardNo = sb.ToString();

                    //机关 
                    getIssue(sb, cbDataSize);
                    cardInfo.Authority = sb.ToString();

                    //有效期 
                    getEffectedDate(sb, cbDataSize);
                    cardInfo.StartTime = sb.ToString();
                    getExpiredDate(sb, cbDataSize);
                    cardInfo.EndTime = sb.ToString();

                    
                    //证件类型
                    //GetCardInfo(105, sb);
                    //if ("1" == sb.ToString())
                    //{
                    //    textBox_CardType.Text = "居民身份证";
                    //}
                    //else if ("3" == sb.ToString())
                    //{
                    //    textBox_CardType.Text = "港澳台居住证";
                    //}
                    //else
                    //{
                    //    textBox_CardType.Text = "外国人居住证";
                    //}

                    //头像
                    int re = GetBmpPhotoExt();
                    int ret = re;
                    int cbPhoto = 256 * 1024;
                    StringBuilder sbPhoto = new StringBuilder(cbPhoto);
                    int nRet = getBMPPhotoBase64(sbPhoto, cbPhoto);
                    byte[] byPhoto = Convert.FromBase64String(sbPhoto.ToString());
                    if (nRet == 1)
                    {
                        cardInfo.Photo = "data:image/bmp;base64," + sbPhoto.ToString();
                    }
                }
            }
            catch (Exception ex)
            {
                log.Info("读取身份证出错:" + ex.Message);
            }
            finally
            {
                if (cardInfo != null)
                {
                    result = JsonConvert.SerializeObject(cardInfo);
                }
            }
            return result;
        }
    }
}