FingerprintCaptureManager.cs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Imaging;
  4. using System.IO;
  5. using System.Management;
  6. using System.Text.RegularExpressions;
  7. using System.Threading;
  8. using libzkfpcsharp;
  9. using Newtonsoft.Json.Linq;
  10. using Sample;
  11. namespace FingerprintScanner
  12. {
  13. public class FingerprintCaptureManager
  14. {
  15. public delegate void FingerprintCapturedHandler(string jsonData);
  16. public event FingerprintCapturedHandler OnFingerprintCaptured;
  17. private IntPtr _deviceHandle = IntPtr.Zero;
  18. private byte[] _fpBuffer;
  19. private byte[] _templateBuffer = new byte[2048];
  20. private int _width = 0;
  21. private int _height = 0;
  22. private int _dpi = 0;
  23. private string _deviceId = "";
  24. private string _deviceStatus = "INACTIVE";
  25. private Thread _captureThread;
  26. private volatile bool _isCapturing = false;
  27. private const string TargetVid = "1B55";
  28. public void SetDeviceInfo(string deviceId, string deviceStatus)
  29. {
  30. _deviceId = deviceId;
  31. _deviceStatus = deviceStatus;
  32. Console.WriteLine($"[Info] Device info set: ID={_deviceId}, Status={_deviceStatus}");
  33. }
  34. /// <summary>
  35. /// Detect and return the serial number of the first connected USB device with VID=1B55
  36. /// </summary>
  37. public string DetectDeviceByVid()
  38. {
  39. Console.WriteLine($"[Info] Detecting USB devices with VID={TargetVid}...");
  40. var devices = GetConnectedUSBDevices();
  41. foreach (var dev in devices)
  42. {
  43. int lastIndex = dev.DeviceID.LastIndexOf('\\');
  44. string serialNumber = lastIndex >= 0 ? dev.DeviceID.Substring(lastIndex + 1) : "";
  45. string vid = GetMatch(dev.DeviceID, @"VID_(\w{4})");
  46. Console.WriteLine($"[Debug] Device found - VID: {vid}, Serial: {serialNumber}");
  47. if (vid.Equals(TargetVid, StringComparison.OrdinalIgnoreCase))
  48. {
  49. Console.WriteLine($"[Info] Matching device detected: Serial={serialNumber}");
  50. return serialNumber;
  51. }
  52. }
  53. Console.WriteLine("[Warning] No matching USB device with target VID found.");
  54. return "";
  55. }
  56. /// <summary>
  57. /// Start fingerprint capture on the detected device with VID=1B55
  58. /// </summary>
  59. public void Start()
  60. {
  61. if (_isCapturing)
  62. {
  63. Console.WriteLine("[Warning] Capture already running.");
  64. return;
  65. }
  66. string detectedSerial = DetectDeviceByVid();
  67. if (string.IsNullOrEmpty(detectedSerial))
  68. {
  69. Console.WriteLine("[Error] No target USB device detected, aborting capture start.");
  70. return;
  71. }
  72. Console.WriteLine("[Info] Initializing zkfp2 SDK...");
  73. int ret = zkfp2.Init();
  74. if (ret != zkfperrdef.ZKFP_ERR_OK)
  75. {
  76. Console.WriteLine($"[Error] zkfp2.Init failed with code: {ret}");
  77. return;
  78. }
  79. int deviceCount = zkfp2.GetDeviceCount();
  80. Console.WriteLine($"[Info] SDK reports {deviceCount} fingerprint device(s) connected.");
  81. if (deviceCount == 0)
  82. {
  83. Console.WriteLine("[Error] No fingerprint devices detected by SDK.");
  84. zkfp2.Terminate();
  85. return;
  86. }
  87. // Open device only at index 0 (matching old working code behavior)
  88. Console.WriteLine($"[Info] Trying to open device at index 0...");
  89. _deviceHandle = zkfp2.OpenDevice(0);
  90. if (_deviceHandle == IntPtr.Zero)
  91. {
  92. Console.WriteLine("[Error] Failed to open device at index 0.");
  93. zkfp2.Terminate();
  94. return;
  95. }
  96. Console.WriteLine("[Info] Opened device at index 0.");
  97. // Get device parameters
  98. byte[] paramValue = new byte[4];
  99. int size = 4;
  100. zkfp2.GetParameters(_deviceHandle, 1, paramValue, ref size);
  101. zkfp2.ByteArray2Int(paramValue, ref _width);
  102. Console.WriteLine($"[Info] Device width: {_width}");
  103. size = 4;
  104. zkfp2.GetParameters(_deviceHandle, 2, paramValue, ref size);
  105. zkfp2.ByteArray2Int(paramValue, ref _height);
  106. Console.WriteLine($"[Info] Device height: {_height}");
  107. size = 4;
  108. zkfp2.GetParameters(_deviceHandle, 3, paramValue, ref size);
  109. zkfp2.ByteArray2Int(paramValue, ref _dpi);
  110. Console.WriteLine($"[Info] Device DPI: {_dpi}");
  111. _fpBuffer = new byte[_width * _height];
  112. _deviceStatus = "ACTIVE";
  113. _deviceId = detectedSerial;
  114. _isCapturing = true;
  115. _captureThread = new Thread(CaptureLoop)
  116. {
  117. IsBackground = true
  118. };
  119. _captureThread.Start();
  120. Console.WriteLine($"[Info] Fingerprint capture started on device {_deviceId}");
  121. }
  122. public void Stop()
  123. {
  124. Console.WriteLine("[Info] Stopping fingerprint capture...");
  125. _isCapturing = false;
  126. _captureThread?.Join();
  127. if (_deviceHandle != IntPtr.Zero)
  128. {
  129. Console.WriteLine("[Info] Closing device handle...");
  130. zkfp2.CloseDevice(_deviceHandle);
  131. _deviceHandle = IntPtr.Zero;
  132. }
  133. Console.WriteLine("[Info] Terminating SDK...");
  134. zkfp2.Terminate();
  135. _deviceStatus = "INACTIVE";
  136. Console.WriteLine("[Info] Fingerprint capture stopped.");
  137. }
  138. private void CaptureLoop()
  139. {
  140. Console.WriteLine("[Info] Capture loop started.");
  141. while (_isCapturing)
  142. {
  143. int templateLength = 2048;
  144. int ret = zkfp2.AcquireFingerprint(_deviceHandle, _fpBuffer, _templateBuffer, ref templateLength);
  145. if (ret == zkfp.ZKFP_ERR_OK)
  146. {
  147. Console.WriteLine("[Info] Fingerprint acquired.");
  148. using (MemoryStream ms = new MemoryStream())
  149. {
  150. BitmapFormat.GetBitmap(_fpBuffer, _width, _height, ms);
  151. byte[] bmpBytes = ms.ToArray();
  152. string bmpBase64 = Convert.ToBase64String(bmpBytes);
  153. string templateBase64 = Convert.ToBase64String(_templateBuffer, 0, templateLength);
  154. var json = new JObject
  155. {
  156. ["deviceInfo"] = new JObject
  157. {
  158. ["deviceId"] = _deviceId,
  159. ["deviceStatus"] = _deviceStatus,
  160. ["width"] = _width,
  161. ["height"] = _height,
  162. ["dpi"] = _dpi
  163. },
  164. ["imageData"] = bmpBase64,
  165. ["templateData"] = templateBase64
  166. };
  167. // Safe event invoke
  168. OnFingerprintCaptured?.Invoke(json.ToString());
  169. }
  170. }
  171. else if (ret == -7)
  172. {
  173. // No finger detected, silently wait
  174. }
  175. else if (ret == -8)
  176. {
  177. // Capture timeout or bad scan, silently wait
  178. }
  179. else
  180. {
  181. Console.WriteLine($"[Warning] AcquireFingerprint returned unexpected code: {ret}");
  182. }
  183. Thread.Sleep(200); // match old working code
  184. }
  185. Console.WriteLine("[Info] Capture loop ended.");
  186. }
  187. public static USBDeviceInfo[] GetConnectedUSBDevices()
  188. {
  189. var usbDevices = new ManagementObjectSearcher("SELECT * FROM Win32_USBHub").Get();
  190. var list = new System.Collections.Generic.List<USBDeviceInfo>();
  191. foreach (var device in usbDevices)
  192. {
  193. string deviceId = device.GetPropertyValue("DeviceID")?.ToString() ?? "";
  194. string desc = device.GetPropertyValue("Description")?.ToString() ?? "";
  195. list.Add(new USBDeviceInfo { DeviceID = deviceId, Description = desc });
  196. }
  197. return list.ToArray();
  198. }
  199. public static string GetMatch(string input, string pattern)
  200. {
  201. var match = Regex.Match(input, pattern);
  202. if (match.Success && match.Groups.Count > 1)
  203. return match.Groups[1].Value;
  204. return "";
  205. }
  206. }
  207. public class USBDeviceInfo
  208. {
  209. public string DeviceID { get; set; }
  210. public string Description { get; set; }
  211. }
  212. }