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

发布于:2025-05-17 ⋅ 阅读:(14) ⋅ 点赞:(0)


使用 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 安装。

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

    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)。

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

    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 设备编程!



网站公告

今日签到

点亮在社区的每一天
去签到