WinUsbNet is an open-source .NET class library that provides a managed wrapper for Microsoft’s WinUSB API. It allows developers writing in C#, VB.NET, or C++.NET to communicate directly with custom USB hardware devices from user-mode code without needing to write or compile a custom Windows kernel driver.
By abstracting away the low-level complexities of the Windows Driver Kit (WDK) and native P/Invoke calls, it translates complex USB configurations into familiar .NET classes and streams. Key Features
Zero Driver Development: Relies entirely on Microsoft’s built-in winusb.sys kernel driver.
Asynchronous & Synchronous Support: Supports both fast, non-blocking asynchronous data transfers and straightforward synchronous commands.
Hotplug Notifications: Built-in event handling automatically alerts your software when a targeted USB device is connected or removed.
Endpoint Control: Provides direct access to read and write to control, bulk, and interrupt endpoints.
Multi-Interface Support: Handles devices with multiple physical USB configurations and interfaces cleanly.
Permissive Licensing: Distributed under the flexible MIT License, making it free for both personal and commercial software development. How It Works Behind the Scenes
To understand WinUsbNet, you have to look at the three layers involved in the communication: Your .NET App →right arrow
WinUsbNet: You interact with clean C# classes (e.g., USBDevice, USBInterface). WinUsbNet →right arrow
winusb.dll: The library uses P/Invoke to send instructions to Windows’ native user-mode sub-layer. winusb.dll →right arrow winusb.sys →right arrow
Hardware: The native library hands requests to the OS kernel driver, which physically pulses data down the USB wire.
⚠️ Prerequisite Note: Windows needs to know that your device should use the generic driver. To do this, you must either configure your device hardware to support Microsoft OS Descriptors (WCID) for automatic driver matching, or provide a simple .inf setup file that pairs your device’s Vendor ID (VID) and Product ID (PID) with a unique Device Interface GUID. Code Examples 1. Initializing and Finding a Device
Devices are discovered using a unique Device Interface GUID that you define in your device’s firmware or .inf file.
using MadWizard.WinUSBNet; // Look for the first connected device matching your custom GUID string myDeviceGuid = “{BB9176E8-924F-4a7e-963A-6DC6A4E87FC2}”; USBDevice device = USBDevice.GetSingleDevice(myDeviceGuid); if (device != null) { Console.WriteLine($“Connected to: {device.Descriptor.Manufacturer}”); } Use code with caution. 2. Reading and Writing Data
Once connected, data is easily pushed or pulled through the interface pipes.
// Access the default first interface of the device USBInterface myInterface = device.Interfaces[0]; // Write bytes out to a Bulk OUT endpoint byte[] dataToSend = new byte[] { 0x01, 0x02, 0x03, 0x04 }; myInterface.OutPipe.Write(dataToSend); // Read bytes in from a Bulk IN endpoint byte[] readBuffer = new byte[64]; int bytesRead = myInterface.InPipe.Read(readBuffer); Use code with caution. Ecosystem and Variants
Depending on the architecture of your application, you may encounter different versions of this library:
TimPaterson/WinUsbNet: A .NET managed interface … – GitHub
Leave a Reply