using System; using System.Globalization; using System.IO; using System.Text; namespace Vinno.IdentificationCardApp { public class IDCardManager { private IDCardInfo _idCardInfo = new IDCardInfo(); private const int IfOpen = 0; //Switch com port automatically private int _portID; private bool _isUsbPort = true; private bool _portIsOpened; private readonly string _tempPath; public IDCardManager() { _tempPath = Path.Combine(Path.GetTempPath(), "IDCardApp"); if (Directory.Exists(_tempPath)==false) { Directory.CreateDirectory(_tempPath); } } public IDCardInfo IDCardInfo { get { return _idCardInfo; } } public bool PortIsOpened { get { return _portIsOpened; } } public bool OpenPort() { _isUsbPort = false; int openPortReturnCode = 0; for (var iPort = 1001; iPort <= 1016; iPort++) { openPortReturnCode = SdtApi.SDT_OpenPort(iPort); if (openPortReturnCode == 0x90) { _portID = iPort; _isUsbPort = true; break; } } if (openPortReturnCode != 0x90) { _portIsOpened = false; return false; } _portIsOpened = true; return true; } public bool ClosePort() { var returnCode = SdtApi.SDT_ClosePort(_portID); if (returnCode == 0x90) { _portIsOpened = false; return true; } return false; } public ReadCardReturnCodeEnum ReadIcCard() { int pucIin = 0; int pucSn = 0; int puiChMsgLen = 0; int puiPhMsgLen = 0; var zpBmpFile = Path.Combine(_tempPath, "zp.bmp"); var zpWltFile = Path.Combine(_tempPath, "zp.wlt"); ReadCardReturnCodeEnum readCardCode = ReadCardReturnCodeEnum.Ok; //Find card var returnCode = SdtApi.SDT_StartFindIDCard(_portID, ref pucIin, IfOpen); if (returnCode == 0x80) { return ReadCardReturnCodeEnum.FindCardFailed; } if (returnCode != 0x80 && returnCode != 0x9F) //0x80 is FindCardFailed, 0x9F is OK, it is workaround to check the device connection error { return ReadCardReturnCodeEnum.DeviceConnectionError; } //Select card returnCode = SdtApi.SDT_SelectIDCard(_portID, ref pucSn, IfOpen); if (returnCode == 0x81) { return ReadCardReturnCodeEnum.SelectCardFailed; } if (returnCode != 0x81 && returnCode != 0x90)//0x81 is FindCardFailed, 0x90 is OK, it is workaround to check the device connection error { return ReadCardReturnCodeEnum.DeviceConnectionError; } try { var objFile = new FileInfo(zpBmpFile); if (objFile.Exists) { objFile.Attributes = FileAttributes.Normal; objFile.Delete(); } objFile = new FileInfo(zpWltFile); if (objFile.Exists) { objFile.Attributes = FileAttributes.Normal; objFile.Delete(); } } catch (Exception ex) { Logger.Error("ReadIcCard", ex); return ReadCardReturnCodeEnum.ClearTempFileFailed; } byte[] pucChMsg = new byte[4096]; byte[] pucPhMsg = new byte[4096]; returnCode = SdtApi.SDT_ReadBaseMsg(_portID, pucChMsg, ref puiChMsgLen, pucPhMsg, ref puiPhMsgLen, IfOpen); if (returnCode != 0x90) { return ReadCardReturnCodeEnum.ReadCardFailed; } try { _idCardInfo = new IDCardInfo(); _idCardInfo.Name = GetString(pucChMsg, 0, 30); //Encoding.Unicode.GetString(pucChMsg, 0, 30).Trim(); _idCardInfo.SexCode = GetString(pucChMsg, 30, 2); //Encoding.Unicode.GetString(pucChMsg, 30, 2).Trim(); _idCardInfo.PeopleCode = GetString(pucChMsg, 32, 4); //Encoding.Unicode.GetString(pucChMsg, 32, 4).Trim(); var strBirthday = GetString(pucChMsg, 36, 16); //Encoding.Unicode.GetString(pucChMsg, 36, 16).Trim(); try { if (string.IsNullOrEmpty(strBirthday) == false) { var birthday = string.Format("{0}-{1}-{2}", strBirthday.Substring(0, 4), strBirthday.Substring(4, 2), strBirthday.Substring(6, 2)); Logger.Info("Birthday: " + birthday); _idCardInfo.Birthday = Convert.ToDateTime(birthday, DateTimeFormatInfo.InvariantInfo); } } catch (Exception ex) { Logger.Error("Birthday", ex); } _idCardInfo.Address = GetString(pucChMsg, 52, 70); //Encoding.Unicode.GetString(pucChMsg, 52, 70).Trim(); _idCardInfo.Idc = GetString(pucChMsg, 122, 36); //Encoding.Unicode.GetString(pucChMsg, 122, 36).Trim(); _idCardInfo.SignAddress = GetString(pucChMsg, 158, 30); //Encoding.Unicode.GetString(pucChMsg, 158, 30).Trim(); var strTem = GetString(pucChMsg, 188, pucChMsg.GetLength(0) - 188); //Encoding.Unicode.GetString(pucChMsg, 188, pucChMsg.GetLength(0) - 188).Trim(); try { if (string.IsNullOrEmpty(strTem) == false) { var strStartDate = string.Format("{0}-{1}-{2}", strTem.Substring(0, 4), strTem.Substring(4, 2), strTem.Substring(6, 2)); Logger.Info("StartDate: " + strStartDate); _idCardInfo.StartDate = Convert.ToDateTime(strStartDate, DateTimeFormatInfo.InvariantInfo); } } catch (Exception ex) { Logger.Error("StartDate", ex); } try { if (string.IsNullOrEmpty(strTem) == false) { strTem = strTem.Substring(8); Logger.Info("EndDate: " + strTem.Trim()); if (strTem.Trim() != "长期") { var strEndDate = string.Format("{0}-{1}-{2}", strTem.Substring(0, 4), strTem.Substring(4, 2), strTem.Substring(6, 2)); Logger.Info("EndDate: " + strEndDate); _idCardInfo.EndDate = Convert.ToDateTime(strEndDate, DateTimeFormatInfo.InvariantInfo); } else { _idCardInfo.EndDate = DateTime.MaxValue; } } } catch (Exception ex) { Logger.Error("EndDate", ex); } //using (FileStream fs = File.Open(zpWltFile, FileMode.Create, FileAccess.ReadWrite)) //{ // fs.Write(pucPhMsg, 0, pucPhMsg.Length); //} //0: call sdtapi error //1: Ok //-1: Picture decode error //-2: wlt file suffix error //-3: wlt file open error //-4: wlt file format error //-5: Software unauthorized; //-6: Device connection error ////Temporary disable the image //returnCode = SdtApi.GetBmp(zpWltFile, _isUsbPort ? 2 : 1); //if (returnCode != 1) //{ // readCardCode = ReadCardReturnCodeEnum.GetPictureFailed; //} //var fileInfo = new FileInfo(zpBmpFile); //if (fileInfo.Exists) //{ // using (var binReader = new BinaryReader(File.Open(zpBmpFile, FileMode.Open))) // { // byte[] bytes = binReader.ReadBytes((int)fileInfo.Length); // binReader.Close(); // var image = new BitmapImage(); // image.BeginInit(); // image.StreamSource = new MemoryStream(bytes); // image.EndInit(); // //Compress the image // using (var m = new MemoryStream()) // { // var encoder = new JpegBitmapEncoder { QualityLevel = 50 }; // encoder.Frames.Add(BitmapFrame.Create(image)); // encoder.Save(m); // _idCardInfo.PicByte = m.ToArray(); // } // } //} } catch (Exception ex) { Logger.Error("ReadIcCard", ex); return ReadCardReturnCodeEnum.ParseCardInfoFailed; } return readCardCode; } private string GetString(byte[] bytes, int index, int count) { try { var str= Encoding.Unicode.GetString(bytes, index, count).Trim(); return str; } catch (Exception ex) { Logger.Error(string.Format("GetString index:{0}, count:{1}", index, count)); Logger.Error("GetString", ex); } return string.Empty; } } }