123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834 |
- using Newtonsoft.Json.Linq;
- using System;
- using System.Linq;
- using System.Runtime.InteropServices;
- using System.Text;
- namespace ThCardReader
- {
- /// <summary>
- /// 华视电子身份证读卡器业务类
- /// 独立于现有的SSCard.dll和NationECCode.dll
- /// </summary>
- class HuaShiIdCardBusiness
- {
- #region 华视SDK P/Invoke声明
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int CVR_InitComm(int Port);
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int CVR_Authenticate();
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int CVR_AuthenticateForNoJudge();
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int CVR_Read_Content(int active);
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int CVR_Read_FPContent();
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int CVR_CloseComm();
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int CVR_GetStatus();
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int GetPeopleName(StringBuilder strTmp, ref int strLen);
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int GetPeopleSex(StringBuilder strTmp, ref int strLen);
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int GetPeopleNation(StringBuilder strTmp, ref int strLen);
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int GetPeopleBirthday(StringBuilder strTmp, ref int strLen);
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int GetPeopleIDCode(StringBuilder strTmp, ref int strLen);
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int GetPeopleAddress(StringBuilder strTmp, ref int strLen);
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int GetDepartment(StringBuilder strTmp, ref int strLen);
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int GetStartDate(StringBuilder strTmp, ref int strLen);
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int GetEndDate(StringBuilder strTmp, ref int strLen);
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int GetBMPData(byte[] pData, ref int pLen);
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int GetJpgData(byte[] jpgData, ref int pLen);
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int GetSexCode(byte[] sexData, ref int pLen);
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int GetNationCode(byte[] nationData, ref int pLen);
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int GetCertType(byte[] certData, ref int pLen);
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int CVR_GetSAMID(StringBuilder SAMID);
- // 新增:获取照片BASE64编码的函数
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int Getbase64BMPData(byte[] pData, ref int pLen);
- [DllImport("Termb.dll", CallingConvention = CallingConvention.StdCall)]
- private extern static int Getbase64JpgData(byte[] pData, ref int pLen);
- #endregion
- #region 静态变量
- private static bool initialized = false;
- private static int currentPort = 1001; // 默认USB端口1
- #endregion
- #region 公共方法
- /// <summary>
- /// 初始化华视读卡器
- /// </summary>
- /// <param name="port">端口号:1-16为串口COM1-COM16,1001-1016为USB口1-16</param>
- /// <returns>初始化结果</returns>
- public static JObject Initialize(int port = 1001)
- {
- JObject result = new JObject();
-
- try
- {
- currentPort = port;
- int initResult = CVR_InitComm(port);
-
- if (initResult == 1)
- {
- initialized = true;
- result.Add("code", 200);
- result.Add("message", $"华视读卡器初始化成功,端口: {GetPortDescription(port)}");
- result.Add("port", port);
- result.Add("device", "华视电子身份证读卡器");
- }
- else
- {
- initialized = false;
- result.Add("code", 1001);
- result.Add("message", GetInitErrorMessage(initResult));
- result.Add("errorCode", initResult);
- }
- }
- catch (Exception ex)
- {
- initialized = false;
- result.Add("code", 1001);
- result.Add("message", $"初始化异常: {ex.Message}");
- }
-
- return result;
- }
- /// <summary>
- /// 读取身份证信息
- /// </summary>
- /// <param name="savePath">照片保存路径,为空则不保存照片</param>
- /// <param name="autoClose">读卡后是否自动关闭连接(默认false,但URL调用时建议true)</param>
- /// <returns>身份证信息</returns>
- public static JObject ReadIdCard(string savePath = "", bool autoClose = false)
- {
- if (!initialized)
- {
- var initResult = Initialize();
- if ((int)initResult["code"] != 200)
- {
- return initResult;
- }
- }
- JObject result = new JObject();
-
- try
- {
- // 1. 检测设备状态
- int status = CVR_GetStatus();
- if (status != 1)
- {
- result.Add("code", 1001);
- result.Add("message", "读卡器设备状态异常");
- return result;
- }
- // 2. 卡认证
- int authResult = CVR_Authenticate();
- if (authResult != 1)
- {
- result.Add("code", 1001);
- result.Add("message", GetAuthErrorMessage(authResult));
- result.Add("errorCode", authResult);
- return result;
- }
- // 3. 读取身份证
- int readResult = CVR_Read_FPContent();
- if (readResult != 1)
- {
- result.Add("code", 1001);
- result.Add("message", GetReadErrorMessage(readResult));
- result.Add("errorCode", readResult);
- return result;
- }
- // 4. 获取身份证信息
- var idCardInfo = GetIdCardInformation();
-
- // 5. 如果需要照片且上面读取失败,尝试使用CVR_Read_Content读取照片
- if (idCardInfo["photoBase64"] == null || string.IsNullOrEmpty(idCardInfo["photoBase64"].ToString()))
- {
- Console.WriteLine("使用CVR_Read_Content重新读取以获取照片数据...");
- int contentReadResult = CVR_Read_Content(1); // active=1表示读取照片
- if (contentReadResult == 1)
- {
- Console.WriteLine("CVR_Read_Content读取成功,重新获取照片数据");
- // 重新获取照片信息
- string newPhotoBase64 = GetIdCardPhotoBase64();
- if (!string.IsNullOrEmpty(newPhotoBase64) && newPhotoBase64.Length > 50)
- {
- idCardInfo["photoBase64"] = newPhotoBase64;
- idCardInfo["hasPhoto"] = true;
- // 重新判断格式
- if (newPhotoBase64.StartsWith("/9j/") || newPhotoBase64.StartsWith("iVBORw0KGgo"))
- {
- idCardInfo["photoFormat"] = "JPEG";
- }
- else if (newPhotoBase64.StartsWith("Qk") || newPhotoBase64.StartsWith("BM"))
- {
- idCardInfo["photoFormat"] = "BMP";
- }
- else
- {
- idCardInfo["photoFormat"] = "UNKNOWN";
- }
- idCardInfo["photoSize"] = newPhotoBase64.Length;
- }
- }
- }
- // 6. 保存照片(如果指定了路径)
- if (!string.IsNullOrEmpty(savePath))
- {
- SaveIdCardPhoto(savePath);
- }
- result.Add("code", 200);
- result.Add("type", "huashi_idcard");
- result.Add("message", "华视读卡器读取身份证成功");
- result.Add("data", idCardInfo);
- result.Add("device", "华视电子身份证读卡器");
- // 7. 自动关闭连接(如果启用)
- if (autoClose)
- {
- Close();
- result.Add("autoClose", true);
- result.Add("closeMessage", "读卡完成后已自动关闭连接");
- }
- }
- catch (Exception ex)
- {
- // 异常时重置初始化状态,下次自动重新初始化(模仿SSCard.dll的自愈机制)
- initialized = false;
- result.Add("code", 1001);
- result.Add("message", $"读取身份证异常: {ex.Message}(设备将在下次使用时自动重新初始化)");
- }
- return result;
- }
- /// <summary>
- /// 连续读卡模式(不需要每次拿起放下)
- /// </summary>
- /// <param name="savePath">照片保存路径</param>
- /// <param name="autoClose">读卡后是否自动关闭连接(默认false,但URL调用时建议true)</param>
- /// <returns>身份证信息</returns>
- public static JObject ReadIdCardContinuous(string savePath = "", bool autoClose = false)
- {
- if (!initialized)
- {
- var initResult = Initialize();
- if ((int)initResult["code"] != 200)
- {
- return initResult;
- }
- }
- JObject result = new JObject();
-
- try
- {
- // 使用连续读卡认证
- int authResult = CVR_AuthenticateForNoJudge();
- if (authResult != 1)
- {
- result.Add("code", 1001);
- result.Add("message", "连续读卡认证失败");
- return result;
- }
- // 读取身份证
- int readResult = CVR_Read_FPContent();
- if (readResult != 1)
- {
- result.Add("code", 1001);
- result.Add("message", GetReadErrorMessage(readResult));
- return result;
- }
- // 获取信息
- var idCardInfo = GetIdCardInformation();
-
- // 保存照片
- if (!string.IsNullOrEmpty(savePath))
- {
- SaveIdCardPhoto(savePath);
- }
- result.Add("code", 200);
- result.Add("type", "huashi_idcard_continuous");
- result.Add("message", "华视读卡器连续读取身份证成功");
- result.Add("data", idCardInfo);
- result.Add("device", "华视电子身份证读卡器");
- // 自动关闭连接(如果启用)
- if (autoClose)
- {
- Close();
- result.Add("autoClose", true);
- result.Add("closeMessage", "读卡完成后已自动关闭连接");
- }
- }
- catch (Exception ex)
- {
- // 异常时重置初始化状态,下次自动重新初始化(模仿SSCard.dll的自愈机制)
- initialized = false;
- result.Add("code", 1001);
- result.Add("message", $"连续读取身份证异常: {ex.Message}(设备将在下次使用时自动重新初始化)");
- }
- return result;
- }
- /// <summary>
- /// 获取设备状态
- /// </summary>
- /// <returns>设备状态信息</returns>
- public static JObject GetDeviceStatus()
- {
- JObject result = new JObject();
-
- try
- {
- if (!initialized)
- {
- // 支持自动初始化,模仿SSCard.dll的行为
- var initResult = Initialize();
- if ((int)initResult["code"] != 200)
- {
- result.Add("code", 1001);
- result.Add("message", "设备未初始化且初始化失败");
- result.Add("initialized", false);
- result.Add("initError", initResult["message"].ToString());
- return result;
- }
- }
- int status = CVR_GetStatus();
-
- result.Add("code", 200);
- result.Add("initialized", true);
- result.Add("port", currentPort);
- result.Add("portDescription", GetPortDescription(currentPort));
- result.Add("deviceStatus", status == 1 ? "正常" : "异常");
- result.Add("statusCode", status);
- result.Add("device", "华视电子身份证读卡器");
-
- // 获取安全模块号
- StringBuilder samId = new StringBuilder(256);
- int samResult = CVR_GetSAMID(samId);
- if (samResult == 1)
- {
- result.Add("samId", samId.ToString().Trim());
- }
- }
- catch (Exception ex)
- {
- // 异常时重置初始化状态
- initialized = false;
- result.Add("code", 1001);
- result.Add("message", $"获取设备状态异常: {ex.Message}(设备将在下次使用时自动重新初始化)");
- }
- return result;
- }
- /// <summary>
- /// 关闭华视读卡器连接
- /// </summary>
- /// <returns>关闭结果</returns>
- public static JObject Close()
- {
- JObject result = new JObject();
-
- try
- {
- if (initialized)
- {
- int closeResult = CVR_CloseComm();
- initialized = false;
-
- result.Add("code", 200);
- result.Add("message", "华视读卡器连接已关闭");
- result.Add("closeResult", closeResult);
- }
- else
- {
- result.Add("code", 200);
- result.Add("message", "华视读卡器未初始化,无需关闭");
- }
- }
- catch (Exception ex)
- {
- result.Add("code", 1001);
- result.Add("message", $"关闭连接异常: {ex.Message}");
- }
- return result;
- }
- #endregion
- #region 私有辅助方法
- /// <summary>
- /// 获取身份证完整信息
- /// </summary>
- /// <returns>身份证信息对象</returns>
- private static JObject GetIdCardInformation()
- {
- JObject info = new JObject();
-
- // 基本信息
- info.Add("name", GetStringData("name"));
- info.Add("sex", GetStringData("sex"));
- info.Add("nation", GetStringData("nation"));
- info.Add("birthday", GetStringData("birthday"));
- info.Add("idCode", GetStringData("idCode"));
- info.Add("address", GetStringData("address"));
- info.Add("department", GetStringData("department"));
- info.Add("startDate", GetStringData("startDate"));
- info.Add("endDate", GetStringData("endDate"));
-
- // 代码信息
- info.Add("sexCode", GetCodeData("sexCode"));
- info.Add("nationCode", GetCodeData("nationCode"));
- info.Add("certType", GetCodeData("certType"));
-
- // 照片信息(BASE64编码)
- string photoBase64 = GetIdCardPhotoBase64();
- info.Add("photoBase64", photoBase64);
- info.Add("hasPhoto", !string.IsNullOrEmpty(photoBase64));
-
- // 如果有照片,添加照片格式信息
- if (!string.IsNullOrEmpty(photoBase64))
- {
- // 根据BASE64前缀判断图片格式
- if (photoBase64.StartsWith("/9j/") || photoBase64.StartsWith("iVBORw0KGgo"))
- {
- info.Add("photoFormat", "JPEG");
- }
- else if (photoBase64.StartsWith("Qk") || photoBase64.StartsWith("BM"))
- {
- info.Add("photoFormat", "BMP");
- }
- else
- {
- info.Add("photoFormat", "UNKNOWN");
- }
-
- info.Add("photoSize", photoBase64.Length);
- }
-
- return info;
- }
- /// <summary>
- /// 安全获取字符串数据
- /// </summary>
- /// <param name="fieldName">字段名</param>
- /// <returns>获取到的字符串</returns>
- private static string GetStringData(string fieldName)
- {
- try
- {
- StringBuilder buffer = new StringBuilder(512);
- int len = 512;
- int result = 0;
-
- switch (fieldName)
- {
- case "name":
- result = GetPeopleName(buffer, ref len);
- break;
- case "sex":
- result = GetPeopleSex(buffer, ref len);
- break;
- case "nation":
- result = GetPeopleNation(buffer, ref len);
- break;
- case "birthday":
- result = GetPeopleBirthday(buffer, ref len);
- break;
- case "idCode":
- result = GetPeopleIDCode(buffer, ref len);
- break;
- case "address":
- result = GetPeopleAddress(buffer, ref len);
- break;
- case "department":
- result = GetDepartment(buffer, ref len);
- break;
- case "startDate":
- result = GetStartDate(buffer, ref len);
- break;
- case "endDate":
- result = GetEndDate(buffer, ref len);
- break;
- default:
- return "";
- }
-
- return result == 1 ? buffer.ToString().Trim() : "";
- }
- catch
- {
- return "";
- }
- }
- /// <summary>
- /// 安全获取代码数据
- /// </summary>
- /// <param name="fieldName">字段名</param>
- /// <returns>获取到的代码</returns>
- private static string GetCodeData(string fieldName)
- {
- try
- {
- byte[] buffer = new byte[32];
- int len = 32;
- int result = 0;
-
- switch (fieldName)
- {
- case "sexCode":
- result = GetSexCode(buffer, ref len);
- break;
- case "nationCode":
- result = GetNationCode(buffer, ref len);
- break;
- case "certType":
- result = GetCertType(buffer, ref len);
- break;
- default:
- return "";
- }
-
- if (result == 1)
- {
- return Encoding.Default.GetString(buffer, 0, len).Trim('\0');
- }
- return "";
- }
- catch
- {
- return "";
- }
- }
- /// <summary>
- /// 获取身份证照片的BASE64编码
- /// </summary>
- /// <returns>照片的BASE64编码字符串</returns>
- private static string GetIdCardPhotoBase64()
- {
- try
- {
- Console.WriteLine("开始获取照片BASE64编码...");
-
- // 首先尝试备用方法(获取二进制数据然后手动转换)
- Console.WriteLine("优先尝试备用方法获取二进制数据...");
- string fallbackResult = GetPhotoBase64Fallback();
- if (!string.IsNullOrEmpty(fallbackResult) && fallbackResult.Length > 50 && !fallbackResult.All(c => c == 'A'))
- {
- Console.WriteLine($"备用方法成功,返回长度: {fallbackResult.Length}");
- return fallbackResult;
- }
-
- // 如果备用方法失败,尝试直接获取BASE64(可能某些SDK版本支持)
- Console.WriteLine("备用方法失败,尝试直接获取BASE64...");
-
- // 尝试获取JPG格式的BASE64编码
- byte[] jpgBase64Data = new byte[38862 * 2]; // 文档说明:不超过38862*2字节
- int jpgLen = jpgBase64Data.Length;
- Console.WriteLine($"尝试调用Getbase64JpgData,缓冲区大小: {jpgLen}");
-
- int jpgResult = Getbase64JpgData(jpgBase64Data, ref jpgLen);
- Console.WriteLine($"Getbase64JpgData返回: {jpgResult}, 数据长度: {jpgLen}");
-
- if (jpgResult == 1 && jpgLen > 0)
- {
- // 转换为字符串并去除多余的空字节
- string jpgBase64 = Encoding.Default.GetString(jpgBase64Data, 0, jpgLen).Trim('\0');
- Console.WriteLine($"JPG BASE64长度: {jpgBase64.Length}, 前20字符: {(jpgBase64.Length > 20 ? jpgBase64.Substring(0, 20) : jpgBase64)}");
-
- // 检查是否是有效数据(不全是相同字符)
- if (!string.IsNullOrEmpty(jpgBase64) && jpgBase64.Length > 10 && !jpgBase64.All(c => c == jpgBase64[0]))
- {
- return jpgBase64;
- }
- }
-
- // 尝试获取BMP格式的BASE64编码
- byte[] bmpBase64Data = new byte[38862 * 2]; // 文档说明:不超过38862*2字节
- int bmpLen = bmpBase64Data.Length;
- Console.WriteLine($"尝试调用Getbase64BMPData,缓冲区大小: {bmpLen}");
-
- int bmpResult = Getbase64BMPData(bmpBase64Data, ref bmpLen);
- Console.WriteLine($"Getbase64BMPData返回: {bmpResult}, 数据长度: {bmpLen}");
-
- if (bmpResult == 1 && bmpLen > 0)
- {
- // 转换为字符串并去除多余的空字节
- string bmpBase64 = Encoding.Default.GetString(bmpBase64Data, 0, bmpLen).Trim('\0');
- Console.WriteLine($"BMP BASE64长度: {bmpBase64.Length}, 前20字符: {(bmpBase64.Length > 20 ? bmpBase64.Substring(0, 20) : bmpBase64)}");
-
- // 检查是否是有效数据(不全是相同字符)
- if (!string.IsNullOrEmpty(bmpBase64) && bmpBase64.Length > 10 && !bmpBase64.All(c => c == bmpBase64[0]))
- {
- return bmpBase64;
- }
- }
-
- Console.WriteLine("所有方法都未能获取到有效的照片数据");
- return "";
- }
- catch (Exception ex)
- {
- Console.WriteLine($"获取照片BASE64编码异常: {ex.Message}");
- return "";
- }
- }
- /// <summary>
- /// 备用方法:获取二进制照片数据并手动转换为BASE64
- /// </summary>
- /// <returns>照片的BASE64编码字符串</returns>
- private static string GetPhotoBase64Fallback()
- {
- try
- {
- Console.WriteLine("开始备用照片获取方法...");
-
- // 尝试获取JPG二进制数据
- byte[] jpgData = new byte[38862];
- int jpgLen = jpgData.Length;
- Console.WriteLine($"尝试调用GetJpgData,缓冲区大小: {jpgLen}");
-
- int jpgResult = GetJpgData(jpgData, ref jpgLen);
- Console.WriteLine($"GetJpgData返回: {jpgResult}, 数据长度: {jpgLen}");
-
- if (jpgResult == 1 && jpgLen > 0)
- {
- byte[] actualJpgData = new byte[jpgLen];
- Array.Copy(jpgData, actualJpgData, jpgLen);
- string jpgBase64 = Convert.ToBase64String(actualJpgData);
- Console.WriteLine($"JPG备用方法成功,BASE64长度: {jpgBase64.Length}, 前20字符: {(jpgBase64.Length > 20 ? jpgBase64.Substring(0, 20) : jpgBase64)}");
- return jpgBase64;
- }
-
- // 如果JPG失败,尝试获取BMP二进制数据
- byte[] bmpData = new byte[38862];
- int bmpLen = bmpData.Length;
- Console.WriteLine($"尝试调用GetBMPData,缓冲区大小: {bmpLen}");
-
- int bmpResult = GetBMPData(bmpData, ref bmpLen);
- Console.WriteLine($"GetBMPData返回: {bmpResult}, 数据长度: {bmpLen}");
-
- if (bmpResult == 1 && bmpLen > 0)
- {
- byte[] actualBmpData = new byte[bmpLen];
- Array.Copy(bmpData, actualBmpData, bmpLen);
- string bmpBase64 = Convert.ToBase64String(actualBmpData);
- Console.WriteLine($"BMP备用方法成功,BASE64长度: {bmpBase64.Length}, 前20字符: {(bmpBase64.Length > 20 ? bmpBase64.Substring(0, 20) : bmpBase64)}");
- return bmpBase64;
- }
-
- Console.WriteLine("备用照片获取方法:所有尝试都失败");
- return "";
- }
- catch (Exception ex)
- {
- Console.WriteLine($"备用照片获取方法异常: {ex.Message}");
- return "";
- }
- }
- /// <summary>
- /// 保存身份证照片
- /// </summary>
- /// <param name="savePath">保存路径</param>
- private static void SaveIdCardPhoto(string savePath)
- {
- try
- {
- if (!System.IO.Directory.Exists(savePath))
- {
- System.IO.Directory.CreateDirectory(savePath);
- }
- // 尝试获取BMP格式照片
- byte[] bmpData = new byte[38862];
- int bmpLen = 38862;
- int bmpResult = GetBMPData(bmpData, ref bmpLen);
-
- if (bmpResult == 1 && bmpLen > 0)
- {
- string bmpPath = System.IO.Path.Combine(savePath, $"idcard_photo_{DateTime.Now:yyyyMMddHHmmss}.bmp");
- byte[] actualBmpData = new byte[bmpLen];
- Array.Copy(bmpData, actualBmpData, bmpLen);
- System.IO.File.WriteAllBytes(bmpPath, actualBmpData);
- }
- // 尝试获取JPG格式照片
- byte[] jpgData = new byte[38862];
- int jpgLen = 38862;
- int jpgResult = GetJpgData(jpgData, ref jpgLen);
-
- if (jpgResult == 1 && jpgLen > 0)
- {
- string jpgPath = System.IO.Path.Combine(savePath, $"idcard_photo_{DateTime.Now:yyyyMMddHHmmss}.jpg");
- byte[] actualJpgData = new byte[jpgLen];
- Array.Copy(jpgData, actualJpgData, jpgLen);
- System.IO.File.WriteAllBytes(jpgPath, actualJpgData);
- }
- }
- catch (Exception ex)
- {
- // 照片保存失败不影响主要功能
- System.Diagnostics.Debug.WriteLine($"保存照片失败: {ex.Message}");
- }
- }
- /// <summary>
- /// 获取端口描述
- /// </summary>
- /// <param name="port">端口号</param>
- /// <returns>端口描述</returns>
- private static string GetPortDescription(int port)
- {
- if (port >= 1 && port <= 16)
- {
- return $"COM{port}";
- }
- else if (port >= 1001 && port <= 1016)
- {
- return $"USB{port - 1000}";
- }
- else
- {
- return $"端口{port}";
- }
- }
- /// <summary>
- /// 获取初始化错误信息
- /// </summary>
- /// <param name="errorCode">错误代码</param>
- /// <returns>错误信息</returns>
- private static string GetInitErrorMessage(int errorCode)
- {
- switch (errorCode)
- {
- case 1: return "初始化成功";
- case 2: return "端口打开失败,请检查读卡器连接";
- case -1: return "未知错误";
- case -2: return "动态库加载失败,请检查termb.dll文件";
- default: return $"初始化失败,错误代码: {errorCode}";
- }
- }
- /// <summary>
- /// 获取认证错误信息
- /// </summary>
- /// <param name="errorCode">错误代码</param>
- /// <returns>错误信息</returns>
- private static string GetAuthErrorMessage(int errorCode)
- {
- switch (errorCode)
- {
- case 1: return "卡片认证成功";
- case 2: return "寻卡失败,请重新放置卡片";
- case 3: return "选卡失败,请重新放置卡片";
- case 4: return "未连接读卡器,请检查设备";
- case 0: return "动态库未加载";
- default: return $"卡片认证失败,错误代码: {errorCode}";
- }
- }
- /// <summary>
- /// 获取读卡错误信息
- /// </summary>
- /// <param name="errorCode">错误代码</param>
- /// <returns>错误信息</returns>
- private static string GetReadErrorMessage(int errorCode)
- {
- switch (errorCode)
- {
- case 1: return "读卡成功";
- case 0: return "读身份证失败,请重新尝试";
- case 4: return "身份证读卡器未连接";
- case 99: return "动态库未加载";
- default: return $"读卡失败,错误代码: {errorCode}";
- }
- }
- #endregion
- }
- }
- // 为了支持LINQ扩展方法
- namespace System.Linq
- {
- internal static class EnumerableExtensions
- {
- public static T[] Take<T>(this T[] source, int count)
- {
- if (count >= source.Length) return source;
-
- T[] result = new T[count];
- Array.Copy(source, result, count);
- return result;
- }
- }
- }
|