using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Management; using System.Text.RegularExpressions; using System.Threading; using libzkfpcsharp; using Newtonsoft.Json.Linq; using Sample; namespace FingerprintScanner { public class FingerprintCaptureManager { public delegate void FingerprintCapturedHandler(string jsonData); public event FingerprintCapturedHandler OnFingerprintCaptured; private IntPtr _deviceHandle = IntPtr.Zero; private byte[] _fpBuffer; private byte[] _templateBuffer = new byte[2048]; private int _width = 0; private int _height = 0; private int _dpi = 0; private string _deviceId = ""; private string _deviceStatus = "INACTIVE"; private Thread _captureThread; private volatile bool _isCapturing = false; private const string TargetVid = "1B55"; public void SetDeviceInfo(string deviceId, string deviceStatus) { _deviceId = deviceId; _deviceStatus = deviceStatus; Console.WriteLine($"[Info] Device info set: ID={_deviceId}, Status={_deviceStatus}"); } /// /// Detect and return the serial number of the first connected USB device with VID=1B55 /// public string DetectDeviceByVid() { Console.WriteLine($"[Info] Detecting USB devices with VID={TargetVid}..."); var devices = GetConnectedUSBDevices(); foreach (var dev in devices) { int lastIndex = dev.DeviceID.LastIndexOf('\\'); string serialNumber = lastIndex >= 0 ? dev.DeviceID.Substring(lastIndex + 1) : ""; string vid = GetMatch(dev.DeviceID, @"VID_(\w{4})"); Console.WriteLine($"[Debug] Device found - VID: {vid}, Serial: {serialNumber}"); if (vid.Equals(TargetVid, StringComparison.OrdinalIgnoreCase)) { Console.WriteLine($"[Info] Matching device detected: Serial={serialNumber}"); return serialNumber; } } Console.WriteLine("[Warning] No matching USB device with target VID found."); return ""; } /// /// Start fingerprint capture on the detected device with VID=1B55 /// public void Start() { if (_isCapturing) { Console.WriteLine("[Warning] Capture already running."); return; } string detectedSerial = DetectDeviceByVid(); if (string.IsNullOrEmpty(detectedSerial)) { Console.WriteLine("[Error] No target USB device detected, aborting capture start."); return; } Console.WriteLine("[Info] Initializing zkfp2 SDK..."); int ret = zkfp2.Init(); if (ret != zkfperrdef.ZKFP_ERR_OK) { Console.WriteLine($"[Error] zkfp2.Init failed with code: {ret}"); return; } int deviceCount = zkfp2.GetDeviceCount(); Console.WriteLine($"[Info] SDK reports {deviceCount} fingerprint device(s) connected."); if (deviceCount == 0) { Console.WriteLine("[Error] No fingerprint devices detected by SDK."); zkfp2.Terminate(); return; } // Open device only at index 0 (matching old working code behavior) Console.WriteLine($"[Info] Trying to open device at index 0..."); _deviceHandle = zkfp2.OpenDevice(0); if (_deviceHandle == IntPtr.Zero) { Console.WriteLine("[Error] Failed to open device at index 0."); zkfp2.Terminate(); return; } Console.WriteLine("[Info] Opened device at index 0."); // Get device parameters byte[] paramValue = new byte[4]; int size = 4; zkfp2.GetParameters(_deviceHandle, 1, paramValue, ref size); zkfp2.ByteArray2Int(paramValue, ref _width); Console.WriteLine($"[Info] Device width: {_width}"); size = 4; zkfp2.GetParameters(_deviceHandle, 2, paramValue, ref size); zkfp2.ByteArray2Int(paramValue, ref _height); Console.WriteLine($"[Info] Device height: {_height}"); size = 4; zkfp2.GetParameters(_deviceHandle, 3, paramValue, ref size); zkfp2.ByteArray2Int(paramValue, ref _dpi); Console.WriteLine($"[Info] Device DPI: {_dpi}"); _fpBuffer = new byte[_width * _height]; _deviceStatus = "ACTIVE"; _deviceId = detectedSerial; _isCapturing = true; _captureThread = new Thread(CaptureLoop) { IsBackground = true }; _captureThread.Start(); Console.WriteLine($"[Info] Fingerprint capture started on device {_deviceId}"); } public void Stop() { Console.WriteLine("[Info] Stopping fingerprint capture..."); _isCapturing = false; _captureThread?.Join(); if (_deviceHandle != IntPtr.Zero) { Console.WriteLine("[Info] Closing device handle..."); zkfp2.CloseDevice(_deviceHandle); _deviceHandle = IntPtr.Zero; } Console.WriteLine("[Info] Terminating SDK..."); zkfp2.Terminate(); _deviceStatus = "INACTIVE"; Console.WriteLine("[Info] Fingerprint capture stopped."); } private void CaptureLoop() { Console.WriteLine("[Info] Capture loop started."); while (_isCapturing) { int templateLength = 2048; int ret = zkfp2.AcquireFingerprint(_deviceHandle, _fpBuffer, _templateBuffer, ref templateLength); if (ret == zkfp.ZKFP_ERR_OK) { Console.WriteLine("[Info] Fingerprint acquired."); using (MemoryStream ms = new MemoryStream()) { BitmapFormat.GetBitmap(_fpBuffer, _width, _height, ms); byte[] bmpBytes = ms.ToArray(); string bmpBase64 = Convert.ToBase64String(bmpBytes); string templateBase64 = Convert.ToBase64String(_templateBuffer, 0, templateLength); var json = new JObject { ["deviceInfo"] = new JObject { ["deviceId"] = _deviceId, ["deviceStatus"] = _deviceStatus, ["width"] = _width, ["height"] = _height, ["dpi"] = _dpi }, ["imageData"] = bmpBase64, ["templateData"] = templateBase64 }; // Safe event invoke OnFingerprintCaptured?.Invoke(json.ToString()); } } else if (ret == -7) { // No finger detected, silently wait } else if (ret == -8) { // Capture timeout or bad scan, silently wait } else { Console.WriteLine($"[Warning] AcquireFingerprint returned unexpected code: {ret}"); } Thread.Sleep(200); // match old working code } Console.WriteLine("[Info] Capture loop ended."); } public static USBDeviceInfo[] GetConnectedUSBDevices() { var usbDevices = new ManagementObjectSearcher("SELECT * FROM Win32_USBHub").Get(); var list = new System.Collections.Generic.List(); foreach (var device in usbDevices) { string deviceId = device.GetPropertyValue("DeviceID")?.ToString() ?? ""; string desc = device.GetPropertyValue("Description")?.ToString() ?? ""; list.Add(new USBDeviceInfo { DeviceID = deviceId, Description = desc }); } return list.ToArray(); } public static string GetMatch(string input, string pattern) { var match = Regex.Match(input, pattern); if (match.Success && match.Groups.Count > 1) return match.Groups[1].Value; return ""; } } public class USBDeviceInfo { public string DeviceID { get; set; } public string Description { get; set; } } }