如何获取扫描条形码、二维码设备(模拟键盘方式)

public class BarcodeScannerHook : IDisposable
{
    private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll")]
    private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

    [DllImport("user32.dll")]
    private static extern bool UnhookWindowsHookEx(IntPtr hhk);

    [DllImport("user32.dll")]
    private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

    [DllImport("kernel32.dll")]
    private static extern IntPtr GetModuleHandle(string lpModuleName);

    private const int WH_KEYBOARD_LL = 13;
    private const int WM_KEYDOWN = 0x0100;

    private static IntPtr _hookID = IntPtr.Zero;
    private readonly StringBuilder _barcodeBuffer = new StringBuilder();
    private DateTime _lastKeyTime = DateTime.MinValue;
    private const int ScanTimeout = 100; // 100ms超时

    private static LowLevelKeyboardProc _staticCallback;

    public event Action<string> BarcodeScanned;

    public BarcodeScannerHook()
    {
        InitializeHook();
       
    }

    private void InitializeHook()
    {
        using (var curModule = System.Diagnostics.Process.GetCurrentProcess().MainModule)
        {
            _staticCallback = HookCallback;
            _hookID = SetWindowsHookEx(WH_KEYBOARD_LL, _staticCallback,
                GetModuleHandle(curModule.ModuleName), 0);
        }
    }

    private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
        {
            int vkCode = Marshal.ReadInt32(lParam);

            // 处理按键
            var currentTime = DateTime.Now;
            if ((currentTime - _lastKeyTime).TotalMilliseconds > ScanTimeout)
            {
                _barcodeBuffer.Clear();
            }
            _lastKeyTime = currentTime;

            // 转换按键为字符
            char key = (char)vkCode;
            if (IsValidBarcodeCharacter(key))
            {
                _barcodeBuffer.Append(key);
            }
            else if (vkCode == 13) // 回车键作为终止符
            {
                ProcessBarcode();
            }
        }
        return CallNextHookEx(_hookID, nCode, wParam, lParam);
    }

    private bool IsValidBarcodeCharacter(char c)
    {
        // 根据具体扫码枪类型调整有效字符范围
        return char.IsLetterOrDigit(c) || c == '-' || c == '_';
    }

    private void ProcessBarcode()
    {
        if (_barcodeBuffer.Length > 0)
        {
            string barcode = _barcodeBuffer.ToString().Trim();                
            if (IsValidBarcode(barcode))
            {
                this.BarcodeScanned?.Invoke(barcode);
            }
            _barcodeBuffer.Clear();
        }
    }

    private bool IsValidBarcode(string code)
    {
        // 添加自定义校验逻辑,例如:
        // - 长度校验
        // - 校验位验证
        // - 格式匹配
        return code.Length >= 6 && code.Length <= 20;
    }

    public void Dispose()
    {
        UnhookWindowsHookEx(_hookID);
    }
}

 

如何使用

BarcodeScannerHook  _scannerHook = new BarcodeScannerHook();
 _scannerHook.BarcodeScanned += _scannerHook_BarcodeScanned;

private void _scannerHook_BarcodeScanned(string obj)
{
    Console.WriteLine(obj)
}

 

posted @ 2025-03-24 11:57  我是刹那、  阅读(57)  评论(0)    收藏  举报