新中新身份证阅读器C#实现

最近有个身份证识别功能需要实现,通过整理把接口进行了封装整理,方便其他业务逻辑调用,代码如下:

1、存储信息结构体类

        /// <summary>
        /// 姓名
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]   //ByValTStr           ByValArray     CertVol
        public string Name;
        /// <summary>
        /// 性别
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
        public string Sex;
        /// <summary>
        /// 民族
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
        public string Nation;
        /// <summary>
        /// 出生日期
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 18)]
        public string Born;
        /// <summary>
        /// 住址
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 72)]
        public string Address;
        /// <summary>
        /// 身份证号
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 38)]
        public string IDCardNo;
        /// <summary>
        /// 发证机关
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        public string GrantDept;
        /// <summary>
        /// 有效开始日期
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 18)]
        public string UserLifeBegin;
        /// <summary>
        /// 有效截止日期
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 18)]
        public string UserLifeEnd;
        /// <summary>
        /// 通行证号码
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
        public string PassID;
        /// <summary>
        /// 签发次数
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
        public string IssuesTimes;
        /// <summary>
        /// 保留
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)]
        public string reserved;
        /// <summary>
        /// 照片路径
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)]
        public string PhotoFileName;
        /// <summary>
        /// 证件类型
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
        public string CardType;
        /// <summary>
        /// 英文名
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 122)]
        public string EngName;
        /// <summary>
        /// 证件版本号
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
        public string CertVol;
    }

2、IDCardHelper辅助类

    public class IDCardHelper
    {
        #region 新中新身份证阅读器基础接口

        //
        //				SAM端口函数
        //
        //
        /// <summary>
        /// 查看串口当前波特率(该函数只用于SAM采用RS232串口的情形,如果采用USB接口则不支持该API)
        /// </summary>
        /// <param name="iPort">[in] 整数,表示端口号。此处端口号必须为1-16,表示串口</param>
        /// <param name="puiBaudRate">[out] 无符号整数指针,指向普通串口当前波特率, 默认情况下为115200</param>
        /// <returns>0成功,1失败/不合法,5无法获得该SAM的波特率,该SAM串口不可用</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_GetCOMBaud")]
        public static extern int Syn_GetCOMBaud(int iPort, ref int puiBaudRate);
        /// <summary>
        /// 设置SAM的串口的波特率(该函数只用于SAM采用RS232串口的情形,如果采用USB接口则不支持该API),
        /// 设置成功后,在该SAM和主机注册表中都记录设置后的波特率,保证在SAM重新启动和该套API被重新调用时采用设置后的波特率。
        /// 该函数调用成功后,需要延时5毫秒,然后才能继续与SAM通信
        /// </summary>
        /// <param name="iPort">[in] 整数,表示端口号。此处端口号必须为1-16,表示串口。</param>
        /// <param name="uiCurrBaud">
        /// [in] 无符号整数,调用该API前已设置的业务终端与SAM通信的波特率(SAM出厂时默认,业务终端与SAM通信的波特率为115200).
        /// 业务终端以该波特率与SAM通信,发出设置SAM新波特率的命令.。
        /// uiCurrBaud只能为下列数值之一:115200,57600,38400,19200,9600.如果uiCurrBaud数值不是这些值之一,函数返回0X21;
        /// 如果已设置的波特率与uiCurrBaud不一致, 则函数返回0X02,表示不能设置,调用API不成功。
        /// </param>
        /// <param name="uiSetBaud">
        /// [in] 无符号整数,将要设置的SAM与业务终端通信波特率。
        /// uiSetBaud只能取下列值之一::115200,57600,38400,19200,9600,
        /// 如果输入uiSetBaud参数不是这些数值之一,,函数返回0X21,设置不成功,保持原来的波特率不变。
        /// </param>
        /// <returns>
        /// 0成功,1端口打开失败/端口号不合法,2超时,设置不成功,33 uiCurrBaud 、uiSetBaud输入参数数值错误
        /// </returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_GetCOMBaud")]
        public static extern int Syn_SetCOMBaud(int iPort, int uiCurrBaud, int uiSetBaud);
        /// <summary>
        /// 打开端口
        /// </summary>
        /// <param name="iPort">端口号。1-16(十进制)为串口,1001-1016(十进制)为USB口,9999为USBHID</param>
        /// <returns>0成功,1打开端口失败/端口号不合法</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_OpenPort")]
        public static extern int Syn_OpenPort(int iPort);
        /// <summary>
        /// 关闭端口
        /// </summary>
        /// <param name="iPort">[in]整数,表示端口号</param>
        /// <returns>0成功,1端口不合法</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_ClosePort")]
        public static extern int Syn_ClosePort(int iPort);

        //
        //				SAM类函数
        //
        //
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_SetMaxRFByte")]
        public static extern int Syn_SetMaxRFByte(int iPort, byte ucByte, int bIfOpen);
        /// <summary>
        /// 对SAM复位
        /// </summary>
        /// <param name="iPort">
        /// [in] 整数,表示端口号。
        /// 根据SAM使用的接口不同(分为普通串口SAM和USB口SAM),
        /// 分别使用不同的端口号(目前串口和USB都只支持16个,即串口0001-0016和USB1001-1016)
        /// </param>
        /// <param name="iIfOpen">
        /// [in] 整数,0表示不在该函数内部打开和关闭串口,
        /// 此时确保之前调用了Syn_OpenPort来打开端口,并且在不需要与端口通信时,调用Syn_ClosePort关闭端口;
        /// 非0表示在API函数内部包含了打开端口和关闭端口函数,之前不需要调用Syn_OpenPort,也不用再调用Syn_ClosePort
        /// </param>
        /// <returns>0成功,其他失败(具体参见返回码表)</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_ResetSAM")]
        public static extern int Syn_ResetSAM(int iPort, int iIfOpen);
        /// <summary>
        /// 对SAM进行状态检测
        /// </summary>
        /// <param name="iPort">[in] 整数,表示端口号。参见Syn_ResetSAM</param>
        /// <param name="iIfOpen">[in] 整数,参见Syn_ResetSAM</param>
        /// <returns>0SAM正常,96自检失败,不能接收命令,其他,命令失败</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_GetSAMStatus")]
        public static extern int Syn_GetSAMStatus(int iPort, int iIfOpen);
        /// <summary>
        /// 读取SAM的编号
        /// </summary>
        /// <param name="iPort">[in] 整数,表示端口号。参见Syn_ResetSAM</param>
        /// <param name="pucSAMID">[out] 无符号字符串指针,指向读到的SAM编号, 16字节</param>
        /// <param name="iIfOpen"></param>
        /// <returns>0成功,其他,失败</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_GetSAMID")]
        public static extern int Syn_GetSAMID(int iPort, byte[] pucSAMID, int iIfOpen);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_GetSAMIDToStr")]
        public static extern int Syn_GetSAMIDToStr(int iPort, ref char[] pucSAMID, int iIfOpen);

        //
        //				身份证卡类函数
        //
        //
        /// <summary>
        /// 开始寻卡
        /// </summary>
        /// <param name="iPort">[in] 整数,表示端口号。参见Syn_ResetSAM</param>
        /// <param name="pucIIN">[out] 无符号字符指针,指向读到的IIN</param>
        /// <param name="iIfOpen">[in] 整数,参见Syn_ResetSAM</param>
        /// <returns>0成功,128失败</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_StartFindIDCard")]
        public static extern int Syn_StartFindIDCard(int iPort, ref byte[] pucIIN, int iIfOpen);
        /// <summary>
        /// 选卡
        /// </summary>
        /// <param name="iPort">[in] 整数,表示端口号。参见Syn_ResetSAM</param>
        /// <param name="pucIIN">[out] 无符号字符指针,指向读到的SN</param>
        /// <param name="iIfOpen">[in] 整数,参见Syn_ResetSAM</param>
        /// <returns>0选卡成功,129选卡失败</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_SelectIDCard")]
        public static extern int Syn_SelectIDCard(int iPort, ref byte[] pucIIN, int iIfOpen);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_ReadBaseMsg")]
        public static extern int Syn_ReadBaseMsg(int iPort, ref byte pucCHMsg, ref int puiCHMsgLen, ref byte pucPHMsg, ref int puiPHMsgLen, int iIfOpen);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_ReadBaseMsgToFile")]
        public static extern int Syn_ReadBaseMsgToFile(int iPort, ref char[] pcCHMsgFileName, ref int puiCHMsgLen, ref char[] pcPHMsgFileName, ref int puiPHMsgLen, int iIfOpen);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_ReadBaseFPMsg")]
        public static extern int Syn_ReadBaseFPMsg(int iPort, ref byte pucCHMsg, ref int puiCHMsgLen, ref byte pucPHMsg, ref int puiPHMsgLen, ref byte pucFPMsg, ref int puiFPMsgLen, int iIfOpen);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_ReadBaseFPMsgToFile")]
        public static extern int Syn_ReadBaseFPMsgToFile(int iPort, ref char[] pcCHMsgFileName, ref int puiCHMsgFileLen, ref char[] pcPHMsgFileName, ref int puiPHMsgFileLen, ref char[] pcFPMsgFileName, ref int puiFPMsgFileLen, int iIfOpen);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_ReadNewAppMsg")]
        public static extern int Syn_ReadNewAppMsg(int iPort, ref byte pucAppMsg, ref int puiAppMsgLen, int iIfOpen);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_GetBmp")]
        public static extern int Syn_GetBmp(int iPort, ref char[] Wlt_File);
        /// <summary>
        /// 读取身份证中的基本信息和照片信息,并按设置转化信息和照片
        /// </summary>
        /// <param name="iPort">[in] 整数,表示端口号。参见Syn_ResetSAM</param>
        /// <param name="iIfOpen">[in] 整数,参见Syn_ResetSAM</param>
        /// <param name="pIDCardData">[out] IDCardData信息</param>
        /// <returns>0读取身份证信息成功,1读取身份证信息成功,解码照片不成功,其他.读取身份证信息失败</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_ReadMsg")]
        public static extern int Syn_ReadMsg(int iPort, int iIfOpen, ref IDCardData pIDCardData);
        /// <summary>
        /// 读取身份证中的基本信息和照片信息,并按设置转化信息和照片
        /// </summary>
        /// <param name="iPort">[in] 整数,表示端口号。参见Syn_ResetSAM</param>
        /// <param name="iIfOpen">[in] 整数,参见Syn_ResetSAM</param>
        /// <param name="pIDCardData">[out] IDCardData信息</param>
        /// <param name="cFPhotoname">cFPhotoName返回指纹信息文件名</param>
        /// <returns>0读取身份证信息成功,无指纹信息,1读取身份证信息成功,指纹读取成功,其他.读取身份证信息失败</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_ReadFPMsg")]
        public static extern int Syn_ReadFPMsg(int iPort, int iIfOpen, ref IDCardData pIDCardData, byte[] cFPhotoname);
        /// <summary>
        /// 自动寻找读卡器
        /// </summary>
        /// <returns>0失败,大于0为串口号或者端口号</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_FindReader")]
        public static extern int Syn_FindReader();
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_FindUSBReader")]
        public static extern int Syn_FindUSBReader();
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_BmpToJpeg")]
        public static extern int Syn_BmpToJpeg(ref char[] cBmpName, ref char[] cJpegName);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_PhotoToStrBase64")]
        public static extern int Syn_PhotoToStrBase64(ref char[] cBase64, ref int iLen, ref char[] cPhotoName);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_StrBase64ToPhoto")]
        public static extern int Syn_StrBase64ToPhoto(ref char[] cBase64, int iLen, ref char[] cPhotoName);

        //
        //				设置附加功能函数
        //
        //
        /// <summary>
        /// 设置照片文件存储的路径
        /// </summary>
        ///  //!!!使用64位动态库需要将license.dat放到cPhotoPath指定的目录!!!
        ///  //使用32位动态库需要将license.dat放到C盘根目录
        /// <param name="iOption">[in] 整形,0=C:根目录,	1=当前路径	,2=指定路径</param>
        /// <param name="cPhotoPath">[in] 字符指针。路径名</param>
        /// <returns></returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_SetPhotoPath")]
        public static extern int Syn_SetPhotoPath(int iOption, byte[] cPhotoPath);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_SetPhotoType")]
        public static extern int Syn_SetPhotoType(int iType);
        /// <summary>
        /// 设置照片文件的文件名
        /// </summary>
        /// <param name="iType">[in]整形。0=tmp,1=姓名,2=身份证号,3=姓名_身份证号</param>
        /// <returns>0成功,-1失败</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_SetPhotoName")]
        public static extern int Syn_SetPhotoName(int iType);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_SetPhotoNameEx")]
        public static extern int Syn_SetPhotoNameEx(int iType, ref char[] cPhotoname);
        /// <summary>
        /// 设置返回性别的格式
        /// </summary>
        /// <param name="iType">[in] 整形。0=卡内存储的数据, 1=解释之后的数据</param>
        /// <returns>0成功,-1失败</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_SetSexType")]
        public static extern int Syn_SetSexType(int iType);
        /// <summary>
        /// 设置返回民族的格式
        /// </summary>
        /// <param name="iType">[in]整形。0=卡内存储的数据,1=解释之后的数据,2=解释之后+“族”</param>
        /// <returns>0成功,-1失败</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_SetNationType")]
        public static extern int Syn_SetNationType(int iType);
        /// <summary>
        /// 设置返回出生日期的格式
        /// </summary>
        /// <param name="iType">in] 整形。0=YYYYMMDD,1=YYYY年MM月DD日,2=YYYY.MM.DD,3=YYYY-MM-DD,4=YYYY/MM/DD</param>
        /// <returns>0成功,-1失败</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_SetBornType")]
        public static extern int Syn_SetBornType(int iType);
        /// <summary>
        /// 设置返回有效期开始日期的格式
        /// </summary>
        /// <param name="iType">[in] 整形。0=YYYYMMDD,1=YYYY年MM月DD日,2=YYYY.MM.DD,3=YYYY-MM-DD,4=YYYY/MM/DD</param>
        /// <returns>0成功,-1失败</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_SetUserLifeBType")]
        public static extern int Syn_SetUserLifeBType(int iType);
        /// <summary>
        /// 设置返回有效期结束日期的格式
        /// </summary>
        /// <param name="iType">[in] 整形。0=YYYYMMDD,1=YYYY年MM月DD日,2=YYYY.MM.DD,3=YYYY-MM-DD,4=YYYY/MM/DD</param>
        /// <param name="iOption">[in] 整形。0=长期不转换   1=长期转换为 有效期开始加50年</param>
        /// <returns>0成功,-1失败</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_SetUserLifeEType")]
        public static extern int Syn_SetUserLifeEType(int iType, int iOption);


        //
        //				USBHID函数
        //
        //
        /// <summary>
        /// 复位M1卡片,返回M1卡片的卡号和卡类型
        /// </summary>
        /// <param name="iPort">[in]整形,读卡器的端口号,可以使用Syn_FindReader获得</param>
        /// <param name="pdwCardSN">[out]无符号四字节,返回M1卡片卡号</param>
        /// <param name="pbSize">[out] 无符号字节数组,返回M1卡卡类型</param>
        /// <returns>0成功,其他失败</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_USBHIDM1Reset")]
        public static extern int Syn_USBHIDM1Reset(int iPort, ref UInt32 pdwCardSN, ref byte pbSize);
        /// <summary>
        /// 用密钥验证M1卡
        /// </summary>
        /// <param name="iPort">[in]整形,读卡器的端口号,可以使用Syn_FindReader获得</param>
        /// <param name="KeyType">[in]无符号字节,验证类型,0—密钥A验证 1—密钥B验证</param>
        /// <param name="BlockNo">[in]无符号字节,M1卡块号</param>
        /// <param name="pKey">[in]无符号字节数组,6字节,密钥数组</param>
        /// <returns>0成功,128失败</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_USBHIDM1AuthenKey")]
        public static extern int Syn_USBHIDM1AuthenKey(int iPort, byte KeyType, byte BlockNo, byte[] pKey);
        /// <summary>
        /// 读M1卡
        /// </summary>
        /// <param name="iPort">[in]整形,读卡器的端口号,可以使用Syn_FindReader获得</param>
        /// <param name="BlockNo">[in]无符号字节,M1卡块号</param>
        /// <param name="pBlock">[out]无符号字节数组,16字节,读取的数据</param>
        /// <returns>0成功,其他失败</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_USBHIDM1ReadBlock")]
        public static extern int Syn_USBHIDM1ReadBlock(int iPort, byte BlockNo, byte[] pBlock);
        /// <summary>
        /// 写M1卡
        /// </summary>
        /// <param name="iPort">[in]整形,读卡器的端口号,可以使用Syn_FindReader获得</param>
        /// <param name="BlockNo">[in]无符号字节,M1卡块号</param>
        /// <param name="pBlock">[in]无符号字节数组,16字节,读取的数据</param>
        /// <returns>0成功</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_USBHIDM1WriteBlock")]
        public static extern int Syn_USBHIDM1WriteBlock(int iPort, byte BlockNo, byte[] pBlock);
        /// <summary>
        /// 挂起M1卡
        /// </summary>
        /// <param name="iPort">[in]整形,读卡器的端口号,可以使用Syn_FindReader获得</param>
        /// <returns>0成功</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_USBHIDM1Halt")]
        public static extern int Syn_USBHIDM1Halt(int iPort);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_USBHIDReadFactoryInfo")]
        public static extern int Syn_USBHIDReadFactoryInfo(int iPort, ref byte pFactory, ref byte pVol, ref byte pSerialNo, ref byte pReserved);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_USBHIDWriteFactoryInfo")]
        public static extern int Syn_USBHIDWriteFactoryInfo(int iPort, ref byte pFactory, ref byte pVol, ref byte pSerialNo, ref byte pReserved);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_USBHIDReadUserInfo")]
        public static extern int Syn_USBHIDReadUserInfo(int iPort, ref byte pInfo);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_USBHIDWriteUserInfo")]
        public static extern int Syn_USBHIDWriteUserInfo(int iPort, ref byte pInfo);
        /// <summary>
        /// 获得读卡器支持的最大通讯字节数和版本
        /// </summary>
        /// <param name="iPort">[in]整形,读卡器的端口号,可以使用Syn_FindReader获得</param>
        /// <param name="pSAMMaxByte">[out]无符号字节,读卡器支持的最大通讯字节数</param>
        /// <param name="pARMVol">[out]无符号字节数组,版本号</param>
        /// <returns></returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_USBHIDGetMaxByte")]
        public static extern int Syn_USBHIDGetMaxByte(int iPort, ref byte pSAMMaxByte, ref byte pARMVol);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_USBHIDSendSound")]
        public static extern int Syn_USBHIDSendSound(int iPort, byte ucSound);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_USBHIDControlLED")]
        public static extern int Syn_USBHIDControlLED(int iPort, byte ucLed);
        /// <summary>
        /// 控制蜂鸣器命令(仅A16D-HF)
        /// </summary>
        /// <param name="iPort">[in]整形,读卡器的端口号,可以使用Syn_FindReader获得</param>
        /// <param name="ucType">[in]无符号整形,命令,暂定为0X04</param>
        /// <param name="usTime"> [in]整形,蜂鸣器响时间,毫秒计算</param>
        /// <returns>0成功</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_USBHIDControlBeep")]
        public static extern int Syn_USBHIDControlBeep(int iPort, byte ucType, int usTime);
        /// <summary>
        /// 读取二代证ID号(仅A16D-HF)
        /// </summary>
        /// <param name="iPort"> [in]整形,读卡器的端口号,可以使用Syn_FindReader获得</param>
        /// <param name="pdwCardSN"> [out] 无符号字节数组,长度8字节</param>
        /// <returns>0成功,128失败</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_USBHIDGetSecCardID")]
        public static extern int Syn_USBHIDGetSecCardID(int iPort, byte[] pdwCardSN);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_USBHIDSIMpowerOn")]
        public static extern int Syn_USBHIDSIMpowerOn(int iPort, ref byte ucATR, ref byte ucLen);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_USBHIDSIMpowerOff")]
        public static extern int Syn_USBHIDSIMpowerOff(int iPort);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_USBHIDSIMAPDU")]
        public static extern int Syn_USBHIDSIMAPDU(int iPort, int slen, ref byte datasend, ref int rlen, ref byte datareceive);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_USBHIDSetUserIDCode")]
        public static extern int Syn_USBHIDSetUserIDCode(int iPort, ref byte code, int len);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_USBHIDSetUserIDCode")]
        public static extern int Syn_USBHIDWriteUserMac(int iPort, ref byte pMac);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_USBHIDIsEncryptMode")]
        public static extern int Syn_USBHIDIsEncryptMode(int iPort);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_USBHIDIsEncryptMode")]
        public static extern int Syn_USBHIDdoUpdate(int iPort, ref byte updateBuffer, int bufferLen, int progressCallback);

        //
        //				串口操作M1卡函数
        //
        //
        /// <summary>
        /// 打开串口
        /// </summary>
        /// <param name="iPort">串口号(1-16)</param>
        /// <param name="badurate">波特率(可使用Syn_GetCOMBaud获得)</param>
        /// <returns>0成功,其他失败</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_SerialOpen")]
        public static extern int Syn_SerialOpen(int iPort, int badurate);
        /// <summary>
        /// 关闭串口
        /// </summary>
        /// <param name="iPort">串口号(1-16)</param>
        /// <returns></returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_SerialClose")]
        public static extern int Syn_SerialClose(int iPort);
        /// <summary>
        /// 复位M1卡片,返回M1卡片的卡号和卡类型
        /// </summary>
        /// <param name="iPort">[in]整形,读卡器的端口号,可以使用Syn_FindReader获得</param>
        /// <param name="pdwCardSN">[out]无符号四字节,返回M1卡片卡号</param>
        /// <param name="pbSize">[out] 无符号字节数组,返回M1卡卡类型</param>
        /// <returns>0成功,其他失败</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_SerialM1Reset")]
        public static extern int Syn_SerialM1Reset(int iPort, ref UInt32 pdwCardSN, ref byte pbSize);
        /// <summary>
        /// 用密钥验证M1卡
        /// </summary>
        /// <param name="iPort">[in]整形,读卡器的串口号(1-16),可以使用Syn_FindReader获得</param>
        /// <param name="KeyType">[in]无符号字节,验证类型,0—密钥A验证 1—密钥B验证</param>
        /// <param name="BlockNo">[in]无符号字节,M1卡块号</param>
        /// <param name="pKey">[in]无符号字节数组,6字节,密钥数组</param>
        /// <returns>0成功,128失败</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_SerialM1AuthenKey")]
        public static extern int Syn_SerialM1AuthenKey(int iPort, byte KeyType, byte BlockNo, byte[] pKey);
        /// <summary>
        /// 读M1卡
        /// </summary>
        /// <param name="iPort">[in]整形,读卡器的端口号,可以使用Syn_FindReader获得</param>
        /// <param name="BlockNo">[in]无符号字节,M1卡块号</param>
        /// <param name="pBlock">[out]无符号字节数组,16字节,读取的数据</param>
        /// <returns>0成功,其他失败</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_SerialM1ReadBlock")]
        public static extern int Syn_SerialM1ReadBlock(int iPort, byte BlockNo, byte[] pBlock);
        /// <summary>
        /// 写M1卡
        /// </summary>
        /// <param name="iPort">[in]整形,读卡器的端口号,可以使用Syn_FindReader获得</param>
        /// <param name="BlockNo">[in]无符号字节,M1卡块号</param>
        /// <param name="pBlock">[in]无符号字节数组,16字节,读取的数据</param>
        /// <returns>0成功</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_SerialM1WriteBlock")]
        public static extern int Syn_SerialM1WriteBlock(int iPort, byte BlockNo, byte[] pBlock);
        /// <summary>
        /// 挂起M1卡
        /// </summary>
        /// <param name="iPort">[in]整形,读卡器的端口号,可以使用Syn_FindReader获得</param>
        /// <returns>0成功</returns>
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_SerialM1Halt")]
        public static extern int Syn_SerialM1Halt(int iPort);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_StartFindCPUCard")]
        public static extern int Syn_StartFindCPUCard(int iPort, byte[] ATS, ref int rlen);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_StartRemoveCPUCard")]
        public static extern int Syn_StartRemoveCPUCard(int iPort, byte[] ATS);
        [DllImport("SynIDCardAPI.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, EntryPoint = "Syn_PCTOCPUCard")]
        public static extern int Syn_PCTOCPUCard(int iPort, int slen, byte[] datasend, ref int rlen, byte[] datareceive);

        #endregion

        #region 单例
        private static IDCardHelper _instance = null;
        public static IDCardHelper Interface
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new IDCardHelper();
                }
                return _instance;
            }
        }
        #endregion

        private int m_iPort = 1001;
        private int m_iReadStart = 0;
        private int m_iReadSum = 0;
        private int m_iReadOKSum = 0;
        private byte m_iMaxByte = 0;
        private int m_errNum = 0;
        private bool link = false;

        /// <summary>
        /// 身份证信息
        /// </summary>
        public IDCardData IdCardInfo = new IDCardData();

        /// <summary>
        /// 设置读取到数据的格式
        /// </summary>
        /// <param name="translateType">具体参见API说明</param>
		private void setupDataFormate()
        {
            Syn_SetPhotoType(4);
            Syn_SetPhotoName(0);
            Syn_SetNationType(1);
            Syn_SetSexType(1);
            Syn_SetBornType(0);
            Syn_SetUserLifeBType(3);
            Syn_SetUserLifeEType(3, 0);
        }

        /// <summary>
        /// -2:没有找到读卡器 -3:读卡器连接在串口 -4:打开端口错误 -5:获取最大通信字节数失败 -6:端口9999异常
        /// </summary>
        /// <returns></returns>
        public int FindCard()
        {
            int nRet = 0;
            byte nARMVol = 0;		//版本号	

            nRet = FindUSBDriverDevice();

            if (nRet == 0)
            {
                return -2;
            }
            else
            {
                m_iPort = nRet;
                if (nRet <= 1000)
                {
                    return -3;
                }
            }
            if (m_iPort == 9999)
            {
                do
                {
                    nRet = Syn_OpenPort(m_iPort);
                    if (nRet != 0)
                    {
                        return -4;
                    }

                    nRet = Syn_USBHIDGetMaxByte(m_iPort, ref m_iMaxByte, ref nARMVol);
                    if (nRet != 0)
                    {
                        Syn_ClosePort(m_iPort);
                        return -5;
                    }
                } while (false);
                nRet = Syn_ClosePort(m_iPort);
            }
            return 0;
        }

        /// <summary>
        /// -12:寻卡错误   -13:选卡错误 -10:图片处理错误 -11:完整过程读取身份证信息错误
        /// </summary>
        /// <returns></returns>
        public int ReadIDCardInfo()
        {
            int nRet = 0;
            byte[] pucIIN = new byte[4];
            byte[] pucSN = new byte[8];
            byte[] ctmp = new byte[255];

            nRet = FindCard();
            if (nRet == -2)
            {
                if (link)
                {
                    link = false;
                    return 100;
                }
            }
            else
            {
                if (!link)
                {
                    link = true;
                    return 200;
                }
            }
            if (nRet != 0) return nRet;

            try
            {
                Syn_SetPhotoPath(1, ctmp);
                setupDataFormate();
                nRet = Syn_OpenPort(m_iPort);
                if (nRet == 0)
                {
                    nRet = Syn_StartFindIDCard(m_iPort, ref pucIIN, 0);
                    if (nRet != 0)
                    {
                        Syn_ClosePort(m_iPort);
                        return -12;
                    }
                    Thread.Sleep(50);
                    nRet = Syn_SelectIDCard(m_iPort, ref pucSN, 0);
                    if (nRet != 0)
                    {
                        Syn_ClosePort(m_iPort);
                        return -13;
                    }
                    Thread.Sleep(50);
                    nRet = Syn_ReadMsg(m_iPort, 0, ref IdCardInfo);
                    if (m_iReadStart == 1)
                    {
                        m_iReadSum++;
                    }
                    if (nRet == 0 || nRet == 1)     //0读取身份证信息成功,1读取身份证信息成功,解码照片不成功,其他.读取身份证信息失败
                    {
                        if (m_iReadStart == 1)
                        {
                            m_iReadOKSum++;
                            Syn_ClosePort(m_iPort);
                            return -10;
                        }
                    }
                    else
                    {
                        m_errNum = nRet;
                        Syn_ClosePort(m_iPort);
                        return -11;
                    }
                }
                else
                {
                    return -4;
                }
                if (m_iPort > 0)
                {
                    Syn_ClosePort(m_iPort);
                }
            }
            catch (Exception e)
            {
                return -100;
            }
            return 0;
        }

        /// <summary>
        /// 寻找USB读卡器
        /// </summary>
        /// <returns></returns>
        private int FindUSBDriverDevice()
        {
            int nRet;
            for (int i = 1001; i < 1017; i++)
            {
                nRet = Syn_OpenPort(i);
                if (nRet == 0)
                {
                    nRet = Syn_GetSAMStatus(i, 0);
                    if (nRet == 0)
                    {
                        Syn_ClosePort(i);
                        return i;
                    }
                    Syn_ClosePort(i);
                }
            }
            return 0;
        }

        /// <summary>
        /// 寻找USBHID读卡器
        /// </summary>
        /// <returns></returns>
        private int FindUSBHIDDevice()
        {
            int nRet;
            nRet = Syn_OpenPort(9999);
            if (nRet == 0)
            {
                Syn_ClosePort(9999);
                return 9999;
            }
            return 0;
        }

        /// <summary>
        /// 寻找串口读卡器
        /// </summary>
        /// <returns></returns>
        private int FindSerialDevice()
        {
            int nRet = 0;
            int m_iBaud = 0;
            for (int j = 1; j < 17; j++)
            {
                nRet = Syn_GetCOMBaud(j, ref m_iBaud);
                if (nRet == 0)
                {
                    nRet = Syn_SetCOMBaud(j, m_iBaud, m_iBaud);
                    if (nRet == 0)
                    {
                        Syn_ClosePort(j);
                        return j;
                    }
                    Syn_ClosePort(j);
                }
            }
            return 0;
        }

        /// <summary>
        /// 清空身份证信息
        /// </summary>
        public void ClearIdCardInfo()
        {
            IdCardInfo.Name = "";      //姓名   
            IdCardInfo.Sex = "";       //性别
            IdCardInfo.Nation = "";    //民族
            IdCardInfo.Born = "";      //出生日期
            IdCardInfo.Address = "";   //住址
            IdCardInfo.IDCardNo = "";  //身份证号
            IdCardInfo.GrantDept = ""; //发证机关
            IdCardInfo.UserLifeBegin = ""; // 有效开始日期
            IdCardInfo.UserLifeEnd = "";   // 有效截止日期
            IdCardInfo.PassID = "";        //通行证号码
            IdCardInfo.IssuesTimes = "";   //签发次数
            IdCardInfo.reserved = "";      // 保留
            IdCardInfo.PhotoFileName = "";// 照片路径   
            IdCardInfo.CardType = "";// 证件类型     
            IdCardInfo.EngName = "";// 英文名      
            IdCardInfo.CertVol = "";// 证件版本号   
        }

        /// <summary>
        /// 获取身份证号
        /// </summary>
        /// <returns></returns>
        public string IdNo
        {
            get
            {
                return IdCardInfo.IDCardNo;
            }

        }

        /// <summary>
        /// 获取姓名
        /// </summary>
        /// <returns></returns>
        public string Name
        {
            get
            {
                return IdCardInfo.Name;
            }
        }

        /
        /// 获取性别
        /// @return 性别
        /
        //CString Sex() { return m_idcardData.Sex; };
        public string Sex
        {
            get
            {
                return IdCardInfo.Sex;
            }
        }

        /
        /// 获取年龄
        /// @return 年龄
        /
        //CString Age();
        public string Age
        {
            get
            {
                if (IdCardInfo.Born == "") return "0";
                DateTime date;
                bool isValid = DateTime.TryParseExact(IdCardInfo.Born, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out date);
                if (!isValid) return "0";

                DateTime currentDate = DateTime.Now;
                int age = currentDate.Year - date.Year;
                if (currentDate.Month < date.Month || (currentDate.Month == date.Month && currentDate.Day < date.Day))
                {
                    age--;
                }
                return age.ToString();
            }
        }



    }

3、调用实例

int flag = IDCardHelper.Interface.ReadIDCardInfo();
if (flag == 0)
{
	string idNo = IDCardHelper.Interface.IdNo.Trim();
	string name = IDCardHelper.Interface.Name.Trim();
	string sex = IDCardHelper.Interface.Sex.Trim();
	string age = IDCardHelper.Interface.Age.Trim();
}
else if (flag == 100)
{
	MessageBox.Show("身份证阅读器连接异常,请重新插拔");
}
else if (flag == 200)
{
	MessageBox.Show("身份证阅读器连接正常", true);
}

技术交流请加群:996775415

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萝卜兽编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值