c# usb hid 键盘通信

场景,假设打开 记事本,
扫码枪是键盘模式,
我扫码123456AB 那么他会出现在记事本
如果是123456AC 就只会c#程序弹窗提示扫码枪的内容,不会出现在记事本
PS当时c# 是没有焦点的 程序在后台运行 。

扫码枪是 usb HID 能读到 id 号

img

我是想后台程序能读到扫码枪的内容。与键盘分开

目前使用 HidLibrary 这个库好像读不到信息
请提供一个demo 测试

现成的 C#与USB HID间的通信

监听键盘,可以考虑使用Raw input这个东西:
https://www.codeproject.com/Articles/17123/Using-Raw-Input-from-C-to-handle-multiple-keyboard
使用HidLibrary在C#中检测来自任何USB HID的输入:http://cn.voidcc.com/question/p-rmgblssd-bea.html
C# 中使用HIDlibrary读到扫码枪的内容demo如下:
C# 中HIDlibrary的使用:https://blog.csdn.net/BeanGo/article/details/127919355

```csharp
using System;
using System.IO;
using System.Windows.Forms;
using HidLibrary;

namespace HID_Demo
{
    public partial class Form1 : Form
    {
        private HidDevice _hidDevice;
        private StreamReader _streamReader;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            ScanHidDevices();
        }

        private void ScanHidDevices()
        {
            var hidDevices = HidDevices.Enumerate(0x046d, 0xfee0); // 根据你的扫码枪的Vendor ID和Product ID进行修改
            foreach (var hidDevice in hidDevices)
            {
                if (!string.IsNullOrEmpty(hidDevice.ProductName))
                {
                    listBox1.Items.Add($"设备名称: {hidDevice.ProductName}, VID: {hidDevice.VendorId}, PID: {hidDevice.ProductId}");
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (_hidDevice == null || _streamReader == null) return;
            _streamReader.BaseStream.Seek(0, SeekOrigin.Begin); // 将流指针移动到开始位置,以便读取新数据
            string data = _streamReader.ReadLine(); // 读取一行数据,如果有多个数据行,可以使用 ReadToEnd() 方法一次性读取所有数据
            MessageBox.Show("扫码枪内容: " + data); // 在记事本中显示扫码枪的内容
        }
    }
}

```

可以使用HidLibrary库读取数据

那就写一个简单的demo的测试函数供你参考吧,主要思路就是用那个HidSharp库来读取扫描枪,在控制台显示检查,在OpenDevice函数编码实现你希望实现的逻辑

   测试函数:
        // 找到与扫码枪对应的HID设备
        _hidDevice = HidDevices.Enumerate().FirstOrDefault(device => device.Attributes.VendorId == YOUR_VENDOR_ID && device.Attributes.ProductId == YOUR_PRODUCT_ID);

        if (_hidDevice == null)
        {
            Console.WriteLine("无法找到扫码枪的HID设备。");
            return;
        }

        // 打开HID设备
        _hidDevice.OpenDevice();

        // 附加数据接收事件处理程序
        _hidDevice.Inserted += DeviceAttachedHandler;
        _hidDevice.Removed += DeviceRemovedHandler;
        _hidDevice.MonitorDeviceEvents = true;

        // 准备接收数据
        _hidDevice.ReadReport(OnReport);

        Console.WriteLine("按任意键停止...");
        Console.ReadKey();

        // 关闭HID设备
        _hidDevice.CloseDevice();

下面方法独立存在:
    private static void DeviceAttachedHandler()
    {
        Console.WriteLine("扫码枪已连接。");
    }

    private static void DeviceRemovedHandler()
    {
        Console.WriteLine("扫码枪已断开连接。");
    }

    private static void OnReport(HidReport report)
    {
        if (report.Data.Length > 0)
        {
            // 将原始数据转换为字符串
            string barcode = System.Text.Encoding.Default.GetString(report.Data);
            Console.WriteLine("扫码枪读取内容: " + barcode);
            
            // 在这里添加你的逻辑判断,执行相应的操作
            if (barcode == "123456AC")
            {
                // 执行弹窗操作
                // ...
            }
            else
            {
                // 将内容写入记事本等操作
                // ...
            }
        }

        // 继续接收数据
        _hidDevice.ReadReport(OnReport);
    }

可能缺少权限

要实现C#与USB HID键盘之间的通信,并在后台程序中读取扫码枪的内容,您可以使用HidLibrary库来进行USB HID设备的读取。以下是一个示例代码,演示如何使用HidLibrary库来读取扫码枪的内容:

首先,您需要安装HidLibrary库。您可以通过NuGet包管理器或手动下载并添加该库的引用。

接下来,使用以下代码示例来读取扫码枪的内容:

using HidLibrary;
using System;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace HidKeyboardCommunication
{
    public partial class MainForm : Form
    {
        private HidDevice _hidDevice;
        private StringBuilder _barcodeBuilder;

        public MainForm()
        {
            InitializeComponent();
            _barcodeBuilder = new StringBuilder();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            // 获取已连接的HID设备列表
            var devices = HidDevices.Enumerate().ToList();

            // 根据设备ID号找到扫码枪设备
            var scannerDevice = devices.FirstOrDefault(d => d.Attributes.VendorId == yourVendorId && d.Attributes.ProductId == yourProductId);

            if (scannerDevice != null)
            {
                // 打开扫码枪设备
                scannerDevice.OpenDevice();

                // 注册数据接收事件
                scannerDevice.ReadReport(OnBarcodeDataReceived);
            }
            else
            {
                MessageBox.Show("未找到扫码枪设备!");
            }
        }

        private void OnBarcodeDataReceived(HidReport report)
        {
            // 从HID报告中获取数据
            var data = report.Data;

            // 解析数据并处理扫码枪输入
            foreach (var byteValue in data)
            {
                if (byteValue == 0)
                {
                    // 0表示一次扫码结束
                    var barcode = _barcodeBuilder.ToString();
                    HandleScannedBarcode(barcode);

                    // 清空缓冲区
                    _barcodeBuilder.Clear();
                }
                else
                {
                    // 非0值为扫码数据
                    _barcodeBuilder.Append((char)byteValue);
                }
            }
        }

        private void HandleScannedBarcode(string barcode)
        {
            // 处理扫码枪输入的逻辑
            if (barcode == "123456AB")
            {
                // 将内容发送到记事本
                SendKeys.Send(barcode);
            }
            else if (barcode == "123456AC")
            {
                // 在C#程序中弹窗提示扫码枪内容
                MessageBox.Show(barcode);
            }
            else
            {
                // 其他情况,不做任何处理
            }
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            base.OnFormClosing(e);

            // 关闭HID设备连接
            _hidDevice?.CloseDevice();
        }
    }
}

请注意,您需要将 yourVendorIdyourProductId 替换为实际的扫码枪设备的供应商ID和产品ID。这些信息可以从设备管理器中查找。

在C#中使用USB HID协议进行键盘通信,您可以使用HidSharp库来实现。以下是一个简单的示例代码,演示如何使用USB HID协议模拟键盘按键:

首先,确保您已经安装了HidSharp库。您可以通过NuGet包管理器或从HidSharp的官方网站获取。


using System;
using System.Text;
using HidSharp;

namespace KeyboardCommunication
{
    class Program
    {
        static void Main(string[] args)
        {
            // 查找键盘设备
            var keyboard = FindKeyboardDevice();

            if (keyboard != null)
            {
                // 打开键盘设备
                using (var device = keyboard.OpenDevice())
                {
                    // 模拟按下和释放键盘按键
                    SendKeyStroke(device, Keycode.A);
                    SendKeyStroke(device, Keycode.B);
                }
            }
            else
            {
                Console.WriteLine("未找到键盘设备");
            }

            Console.ReadLine();
        }

        static HidDevice FindKeyboardDevice()
        {
            // 获取系统中所有的HID设备
            var loader = new HidDeviceLoader();
            var devices = loader.GetDevices();

            // 遍历设备,查找符合键盘设备标识的设备
            foreach (var device in devices)
            {
                if (device.VendorID == 0x1234 && device.ProductID == 0x5678)
                {
                    return device;
                }
            }

            return null;
        }

        static void SendKeyStroke(HidDevice device, Keycode key)
        {
            // 构造键盘输入报文
            byte[] report = new byte[8];
            report[2] = (byte)key;

            // 发送报文
            device.Write(report);
        }
    }

    enum Keycode : byte
    {
        A = 0x04,
        B = 0x05,
        // 其他键盘按键的定义
    }
}

请注意,以上代码只是一个简单的示例,假设键盘设备的厂商ID(Vendor ID)为0x1234,产品ID(Product ID)为0x5678。您需要根据实际情况修改这些值。

此外,要发送其他键盘按键,您可以参考键盘扫描码表,根据需要设置Keycode枚举中的键码。还可以根据具体的HID设备规范,调整发送的报文格式。

注意:使用USB HID协议进行键盘通信时,操作系统可能会要求以管理员权限运行应用程序。

以下答案参考newbing,回答由博主波罗歌编写:
要实现C#程序后台读取USB HID扫码枪的内容并作出不同的处理,可以按照以下步骤进行:

  1. 首先,你需要引用System.ManagementSystem.Windows.Forms命名空间,以及下载并安装HidLibrary库。

  2. 打开记事本,并确保焦点不在记事本窗口上。

  3. 在C#中,你可以使用WM_INPUT消息来获取HID设备的输入信息。首先,需要定义WM_INPUT的常量和结构体,以及导入Win32 API函数。

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

public class Program
{
    // 定义 WM_INPUT 常量
    private const int WM_INPUT = 0x00FF;
    
    // 定义 RID_HEADER 结构体
    [StructLayout(LayoutKind.Sequential)]
    public struct RID_HEADER
    {
        public int dwType;
        public int dwSize;
        public IntPtr hDevice;
        public IntPtr wParam;
    }
    
    // 导入 RegisterRawInputDevices 函数
    [DllImport("User32.dll")]
    extern static bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevices, uint uiNumDevices, uint cbSize);
    
    // 导入 GetRawInputData 函数
    [DllImport("User32.dll")]
    extern static uint GetRawInputData(IntPtr hRawInput, uint uiCommand, IntPtr pData, ref uint pcbSize, uint cbSizeHeader);
    
    // 导入 FindWindow 函数
    [DllImport("user32.dll")]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    
    // 定义 RAWINPUTDEVICE 结构体
    [StructLayout(LayoutKind.Sequential)]
    public struct RAWINPUTDEVICE
    {
        public ushort usUsagePage;
        public ushort usUsage;
        public uint dwFlags;
        public IntPtr hwndTarget;
    }
    
    // 定义 RawInputEventHandler 委托
    public delegate void RawInputEventHandler(object sender, RawInputEventArgs e);
    
    // 定义 RawInputEventArgs 类
    public class RawInputEventArgs : EventArgs
    {
        public string DeviceName { get; set; }
        public string InputText { get; set; }
    }
}
  1. 创建一个类,用于处理扫码枪输入信息,在该类中注册原始输入设备。
public class BarcodeScanner
{
    // 定义扫码枪的输入缓冲区
    private const int INPUT_BUFFER_SIZE = 64;
    
    // 定义输入设备句柄
    private IntPtr _hWnd;
    
    // 创建事件处理程序
    public event RawInputEventHandler ScanComplete;
    
    // 构造函数
    public BarcodeScanner()
    {
        RegisterRawInput(); // 注册原始输入设备
    }
    
    // 注册原始输入设备
    private void RegisterRawInput()
    {
        RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[1];
        rid[0].usUsagePage = 0x01;
        rid[0].usUsage = 0x06;
        rid[0].dwFlags = 0x00000100;
        rid[0].hwndTarget = _hWnd;
        RegisterRawInputDevices(rid, (uint)rid.Length, (uint)Marshal.SizeOf(rid[0]));
    }
    
    // 处理原始输入事件
    public void HandleRawInput(IntPtr hRawInput)
    {
        uint dataSize = 0;
        IntPtr headerSize = (IntPtr)Marshal.SizeOf(typeof(RID_HEADER));
        
        // 获取原始输入数据的大小
        GetRawInputData(hRawInput, 0x10000003, IntPtr.Zero, ref dataSize, headerSize);
        
        // 分配缓冲区并获取原始输入数据
        IntPtr pData = Marshal.AllocHGlobal((int)dataSize);
        if (GetRawInputData(hRawInput, 0x10000003, pData, ref dataSize, headerSize) == dataSize)
        {
            // 解析原始输入数据
            RID_HEADER header = Marshal.PtrToStructure<RID_HEADER>(pData);
            int bufferSize = header.dwSize - headerSize.ToInt32();
            byte[] buffer = new byte[bufferSize];
            Marshal.Copy(pData + headerSize.ToInt32(), buffer, 0, bufferSize);
            
            // 处理输入数据
            string inputText = System.Text.Encoding.Default.GetString(buffer);
            OnScanComplete(inputText);
        }
        
        Marshal.FreeHGlobal(pData);
    }
    
    // 触发扫码完成事件
    protected void OnScanComplete(string inputText)
    {
        ScanComplete?.Invoke(this, new RawInputEventArgs() { DeviceName = "扫码枪", InputText = inputText });
    }
}
  1. Program类的Main方法中创建BarcodeScanner实例,并注册事件处理程序。
public class Program
{
    // ...
    
    public static void Main(string[] args)
    {
        // ...
        
        BarcodeScanner scanner = new BarcodeScanner();
        scanner.ScanComplete += OnScanComplete;
        
        // ...
    }
    
    private static void OnScanComplete(object sender, RawInputEventArgs e)
    {
        string inputText = e.InputText;
        
        if (inputText == "123456AB")
        {
            // 在记事本中输入文本
            IntPtr hWnd = FindWindow("Notepad", null);
            SetForegroundWindow(hWnd);
            SendKeys.SendWait(inputText);
        }
        else if (inputText == "123456AC")
        {
            // 显示提示框
            MessageBox.Show(inputText, "扫码枪内容");
        }
    }
}

请注意,以上代码只是一个简单示例,实际情况中可能需要根据你的需求进行适当修改。这里的关键是通过原始输入设备注册和处理原始输入事件来读取扫码枪的输入内容,并根据内容作出相应的处理。
如果我的回答解决了您的问题,请采纳!

自己nuget hidsharp 就可以了。

hid设备数据可以直接通过hid协议拿到(鼠标,键盘除外,因为安全原因windows目前不会给应用层传递鼠标,键盘类hid报告)

类似扫描抢数据是可以直接使用hidsharp拿到数据报告的(hid report
至于代码么,你知道“hidsharp”这个关键词了代码到容易获得