如何区分同一PC上两个USB条码扫描器的数据来源并写入SQL Server?
区分两台USB被动条码扫描器的输入来源
这类被动扫描器本质是模拟HID键盘输入,系统默认会将其识别为普通键盘,要区分输入来源,可尝试以下几种实用方案:
方案1:通过Windows API拦截原始输入获取设备标识
利用Windows的Raw Input API捕获键盘输入的底层设备信息,比如设备的供应商ID(VID)、**产品ID(PID)**或设备实例路径,以此区分不同扫描器:
- 在WinForms项目中通过P/Invoke调用
SetWindowsHookEx设置键盘钩子,或直接注册Raw Input设备监听 - 在输入回调中,调用
GetRawInputDeviceInfo获取当前输入设备的硬件信息 - 预先记录两台扫描器的VID/PID,对比后即可判断数据来源
核心代码片段示例:
// 省略完整P/Invoke结构体定义 [DllImport("user32.dll")] static extern uint GetRawInputDeviceInfo(IntPtr hDevice, uint uiCommand, IntPtr pData, ref uint pcbSize); void ProcessRawInput(IntPtr rawInputHandle) { RAWINPUT rawInput = new RAWINPUT(); uint size = (uint)Marshal.SizeOf(rawInput); GetRawInputData(rawInputHandle, RID_INPUT, out rawInput, ref size, Marshal.SizeOf(typeof(RAWINPUTHEADER))); if (rawInput.header.dwType == RIM_TYPEKEYBOARD) { uint deviceInfoSize = 0; GetRawInputDeviceInfo(rawInput.header.hDevice, RIDI_DEVICEINFO, IntPtr.Zero, ref deviceInfoSize); IntPtr deviceInfoPtr = Marshal.AllocHGlobal((int)deviceInfoSize); GetRawInputDeviceInfo(rawInput.header.hDevice, RIDI_DEVICEINFO, deviceInfoPtr, ref deviceInfoSize); RAWINPUTDEVICEINFO deviceInfo = (RAWINPUTDEVICEINFO)Marshal.PtrToStructure(deviceInfoPtr, typeof(RAWINPUTDEVICEINFO)); // 提取设备VID/PID:deviceInfo.hid.dwVendorId、deviceInfo.hid.dwProductId // 对比预存的两台扫描器标识,判断数据来源 } }
方案2:给扫描器配置专属前缀/后缀
绝大多数条码扫描器支持通过扫描配置条码修改输出格式,你可以给两台扫描器分别设置不同的前缀(如[SCAN1]、[SCAN2])或后缀:
- 查找扫描器用户手册,找到「添加前缀/后缀」的配置条码
- 分别用两台扫描器扫描对应配置条码完成设置
- 在WinForms文本框的
TextChanged或KeyPress事件中,检查输入内容的前缀即可判断来源
方案3:使用扫描器厂商提供的SDK
如果是品牌扫描器(如斑马、霍尼韦尔),厂商通常会提供Windows专用SDK,这类SDK支持直接枚举连接设备、获取唯一标识,且数据接收无需依赖模拟键盘输入,可靠性更高:
- 下载对应品牌的SDK并集成到WinForms项目中
- 通过SDK接口枚举所有连接的扫描器,记录每个设备的ID
- 为每个扫描器注册数据接收事件,直接在回调中区分来源
内容的提问来源于stack exchange,提问作者Daryush
相关产品推荐
相关产品推荐

