【使用 C# 获取 USB 设备信息及进行通信】

文章目录

  • [使用 C\# 获取 USB 设备信息及进行通信](# 获取 USB 设备信息及进行通信)
    • [为什么需要获取 USB 设备信息?](#为什么需要获取 USB 设备信息?)
    • [方法一:使用 C\# 库 (推荐)](# 库 (推荐))
      • [1. HidSharp](#1. HidSharp)
      • [2. LibUsbDotNet](#2. LibUsbDotNet)
    • [方法二:直接调用 Windows API (P/Invoke)](#方法二:直接调用 Windows API (P/Invoke))
    • 理解设备通信协议 (用于数据交换)
    • 总结

使用 C# 获取 USB 设备信息及进行通信

作为开发者,有时我们需要在应用程序中识别连接到计算机的 USB 设备,获取它们的详细信息,甚至与它们进行数据交换来控制硬件。本文将介绍如何使用 C# 来实现这些功能。

为什么需要获取 USB 设备信息?

你可能遇到过类似这样的界面:

这些界面显示了连接设备的 Vendor ID (VID)、Product ID (PID)、制造商、产品名称等信息。在开发需要与特定硬件交互的应用程序时,根据这些信息来识别设备是常见的需求。

获取这些信息通常需要与操作系统底层进行交互。虽然可以直接调用 Windows API,但这会涉及复杂的 P/Invoke(Platform Invoke)和结构体处理。幸运的是,有一些优秀的第三方库可以极大地简化这个过程。

方法一:使用 C# 库 (推荐)

使用成熟的 C# 库是获取 USB 设备信息和进行通信的最简便和推荐的方式。这些库封装了底层的 Windows API 或其他跨平台 USB 访问方法,提供了更易于使用的接口。

这里推荐两个常用的 C# USB 库:

1. HidSharp

  • GitHub 地址: https://github.com/videlalvaro/HidSharp

  • 适用范围: 主要用于 Human Interface Device (HID) 设备,如键盘、鼠标、游戏控制器以及许多自定义的 USB 设备。

  • 优点: 专注于 HID 类设备,API 设计相对简洁易懂,方便进行设备枚举和 HID 报告的读写。可以通过 NuGet 安装。

  • 获取信息示例 (概念代码):

    csharp 复制代码
    using HidSharp;
    using System;
    
    // 获取所有连接的HID设备列表
    var devices = DeviceList.Local.GetHidDevices();
    
    Console.WriteLine("发现的 HID 设备:");
    foreach (var device in devices)
    {
        Console.WriteLine($"设备路径: {device.DevicePath}");
        Console.WriteLine($"  Vendor ID (VID): {device.VendorID:X4}"); // 通常以16进制显示
        Console.WriteLine($"  Product ID (PID): {device.ProductID:X4}"); // 通常以16进制显示
        Console.WriteLine($"  制造商: {device.GetManufacturer()}");
        Console.WriteLine($"  产品名称: {device.GetProductName()}");
        Console.WriteLine("---");
    }

2. LibUsbDotNet

  • GitHub 地址: https://github.com/LibUsbDotNet/LibUsbDotNet

  • 适用范围: 提供更底层的 USB 访问能力,支持更广泛的 USB 设备类型和传输模式(控制、批量、中断等)。它是跨平台的 LibUSB 库的 .NET 封装。

  • 优点: 功能强大,灵活,适用于需要进行复杂 USB 通信的场景。可以通过 NuGet 安装,具备跨平台潜力(需安装底层 LibUSB)。

  • 获取信息示例 (概念代码):

    csharp 复制代码
    using LibUsbDotNet;
    using LibUsbDotNet.Main;
    using System;
    
    // 获取所有连接的USB设备
    UsbRegDeviceList allDevices = UsbGlobals.AllDevices;
    
    Console.WriteLine("发现的 USB 设备:");
    foreach (UsbRegistry regDevice in allDevices)
    {
        Console.WriteLine($"设备描述: {regDevice.FullName}");
        Console.WriteLine($"  Vendor ID (VID): {regDevice.Vid:X4}"); // 通常以16进制显示
        Console.WriteLine($"  Product ID (PID): {regDevice.Pid:X4}"); // 通常以16进制显示
        Console.WriteLine($"  制造商: {regDevice.ManufacturerString}");
        Console.WriteLine($"  产品: {regDevice.ProductString}");
        Console.WriteLine($"  序列号: {regDevice.SerialNumber}"); // 如果设备提供
        Console.WriteLine("---");
    }

如何选择库?

  • 如果你主要处理键盘、鼠标、游戏控制器等 HID 类设备,并且只需要进行相对简单的通信(发送/接收 HID 报告),HidSharp 通常是更直接、更易用的选择。
  • 如果你需要与各种类型的 USB 设备进行底层通信,需要灵活控制不同的传输模式,或者希望具备跨平台能力,LibUsbDotNet 可能更适合,但学习和使用起来相对复杂一些。

方法二:直接调用 Windows API (P/Invoke)

作为了解,你也可以通过 C# 直接调用 Windows 提供的 SetupAPI 函数来枚举和查询设备信息。这涉及到使用 [DllImport] 属性导入 C 风格的函数,以及手动定义和操作结构体和指针。这种方法虽然可行,但代码会比较底层和复杂,容易出错,通常不推荐新手使用,除非有特殊需求或出于学习目的。

(在之前的交流中,我们提供了一个使用 SetupAPI 获取 VID/PID 的代码示例,此处不再重复列出,但你可以通过 P/Invoke 方式实现类似功能。)

理解设备通信协议 (用于数据交换)

仅仅获取设备的 VID、PID 等信息只是第一步。如果你想通过代码控制硬件(例如让指示灯亮起、读取传感器数据、发送命令等),你需要与设备进行"数据交换"。而进行数据交换的前提是了解设备的通信协议

设备的通信协议定义了:

  • 你应该发送什么样的数据包(字节序列)作为命令。
  • 设备会返回什么样的数据包作为响应或状态。
  • 数据包中各个字节或字段的含义。

协议是否都一样?

  • 不尽相同。 大多数情况下,一个特定型号的硬件设备有其自己独特的通信协议,特别是厂商自定义设备。
  • 例外:标准 USB 设备类。 如前所述,USB 有标准设备类(HID、Mass Storage 等),这些类的基本通信框架和部分协议是标准化的。但即使在标准类内,设备如何使用这些标准(例如 HID 报告的具体格式和用途)仍然由厂商定义。

如何获取设备的通信协议?

获取设备的通信协议信息是进行底层控制的关键挑战:

  1. 查阅设备制造商的官方文档或 SDK (首选): 这是最权威和详细的信息来源。寻找技术手册、开发者指南,它们通常会详细说明 USB 接口和通信协议。
  2. 查阅 USB 标准设备类规范: 如果设备属于标准类,阅读相关的 USB-IF 规范文档可以帮助你理解底层框架。
  3. 搜索社区和第三方资料: 在论坛、博客、GitHub 上搜索设备型号、VID、PID,看是否有其他开发者分享了协议信息。
  4. 协议逆向工程 (困难且耗时): 如果没有任何文档,最后的手段是使用 USB 协议分析器(硬件或软件如 Wireshark)捕获设备与其原生软件通信时的数据,然后分析数据包来推断协议。这需要专业知识和耐心。

一旦你获取了设备的协议信息,你就可以结合 HidSharpLibUsbDotNet 等库提供的发送和接收数据的方法,在 C# 代码中构建相应的数据包,实现与硬件设备的交互。

总结

使用 C# 获取 USB 设备信息并进行通信,通常推荐使用成熟的第三方库如 HidSharpLibUsbDotNet,它们封装了复杂的底层操作。获取设备信息(VID/PID 等)相对容易,而要实现与设备的双向数据交换(控制硬件),关键在于理解设备特定的通信协议,这通常需要查阅制造商文档或进行研究。

希望这篇文章能帮助你开始在 C# 中探索 USB 设备编程!


相关推荐
冷崖3 小时前
MySQL异步连接池的学习(五)
学习·mysql
知识分享小能手3 小时前
Vue3 学习教程,从入门到精通,Axios 在 Vue 3 中的使用指南(37)
前端·javascript·vue.js·学习·typescript·vue·vue3
所愿ღ4 小时前
JavaWeb-Servlet基础
笔记·servlet
岑梓铭5 小时前
考研408《计算机组成原理》复习笔记,第五章(2)——CPU指令执行过程
笔记·考研·408·计算机组成原理·计组
七七&5566 小时前
2024年08月13日 Go生态洞察:Go 1.23 发布与全面深度解读
开发语言·网络·golang
java坤坤6 小时前
GoLand 项目从 0 到 1:第八天 ——GORM 命名策略陷阱与 Go 项目启动慢问题攻坚
开发语言·后端·golang
元清加油6 小时前
【Golang】:函数和包
服务器·开发语言·网络·后端·网络协议·golang
健康平安的活着7 小时前
java之 junit4单元测试Mockito的使用
java·开发语言·单元测试
焄塰7 小时前
Ansible 管理变量和事实
学习·centos·ansible
DjangoJason8 小时前
C++ 仿RabbitMQ实现消息队列项目
开发语言·c++·rabbitmq