How to connect to a USB device (UWP app)

Summary

  • How to use the DeviceWatcher object to detect devices
  • How to open the device for communication
  • How to close the device when you are finished using information technology

Important APIs

  • UsbDevice
  • DeviceWatcher

When you write a UWP app that interacts with a USB device, the app can send control commands, get device information, and read and write information to/from bulk and interrupt endpoints. Before y'all tin do all that, you must notice the device and establish connection.

Earlier you start...

  • This is the first topic in a series. Before you starting time this tutorial, you must have created a basic Visual Studio project that you lot can extend in this tutorial. Read Getting started with UWP apps for more info.
  • Code examples are based on the CustomUsbDeviceAccess sample. You tin can download the consummate sample from this code gallery page.
  • The USB device used in tutorial is the SuperMUTT device.
  • In society to use the Windows.Devices.Usb namespace to write a Windows app that interacts with a USB device, the device must have the Winusb.sys driver loaded as its function commuter. Winusb.sys is provided by Microsoft and is included with Windows in the \Windows\System32\drivers folder.

Flowchart: Finding the device

To connect to a USB device, you must commencement find the device based on various discovery patterns and then connect to it:

  • Connect to any USB device with a specific device interface GUID.
  • Connect to a USB device with a particular Vendor ID and Product ID and that has a specific device interface GUID.
  • Connect to a USB device with a particular Vendor ID and Product ID without knowing the device interface GUID.
  • Connect to a USB device which has known device class.

usb device discovery.

Key concepts

What is a device interface GUID?

A kernel-model driver, during its initialization, register and exposes a GUID called the device interface GUID. Typically, the app uses the exposed GUID to detect the associated driver and its device, and and so open a handle to the device. The retrieved handle is used for subsequent read and write operations.

However, in the case of Winusb.sys, instead of the driver exposing the device interface GUID, information technology can be provided in 1 of ii means:

  • In the device'south MS Bone descriptors. The device manufacturer sets DeviceInterfaceGUID as a custom holding in the extended properties descriptor in the device. For more details, see the "Extended Properties Descriptors" document in Microsoft OS Descriptors.
  • If you installed Winusb.sys manually through a custom INF, the INF registered a GUID in the INF. Run into WinUSB (Winusb.sys) Installation.

If a device interface GUID is found for the device, your UWP app can notice all devices that friction match that device interface GUID.

How is USB device identification shown in Windows?

Every USB device must have two pieces of data: vendor ID and production ID.

USB-IF assigns those identifiers and the device manufacturer must betrayal them in the device. And so how tin y'all obtain that information?

  • Even when the device doesn't have a device commuter loaded, that is, Windows detects information technology as an "Unknown Device", you can still view the identifiers in the Device Manager in the Hardware Id property value. That value is a combination of those two identifiers. For example, for the SuperMUTT device, the Hardware Id is "USB\VID_045E&PID_F001"; vendor id is "0x045E" and product id is "0xF001".

  • If in that location is an INF for the device, obtain that cord from the Models section.

  • You can inspect various registry settings. The easiest fashion is to run across the

    HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\USB\<hardware id>

    For more than information, see USB Device Registry Entries.

  • Hardware ID is used past the app manifest to identify the device.

    <Device Id="vidpid:045e f001">

Your UWP app can discover all devices that friction match a specific vendor and product ids. You lot can narrow the search results past specifying the device interface GUID.

What are USB device classes?

Nigh USB devices suit to device class specifications approved by USB-IF. By using those specifications, devices of similar nature can exhibit their functionality in a standard style. The biggest reward of this approach is that the device tin can use a Microsoft provided in-box class driver or the generic Winusb.sys driver.

Some devices might not follow a USB-IF specification. Instead they expose vendor-defined functionality. For such devices, either the vendor must provide the device driver or Winusb.sys can be used.

Whether a device is vendor-defined or conforms to a device course, it must describe this device form related data:

  • Form code: Indicates the device course to which the device belongs.
  • Bracket lawmaking: Within the device course, indicates the subclass of device.
  • Protocol code: The protocol that the device uses.

For example, the SuperMUTT device is a vendor-defined device and that data is indicated past course code is FF. If your device shows class code equally FEh, subclass code equally 02h, and protocol code 00h, y'all tin can conclude that the device is a class-compliant IrDA bridge device. Your UWP app can communicate with devices that belong to these device classes:

  • ActiveSync
  • CdcControl
  • DeviceFirmwareUpdate
  • IrDA
  • Measurement
  • PalmSync
  • PersonalHealthcare
  • Concrete
  • VendorSpecific

Your UWP app can find all devices that match a specific set up of class, subclass, and protocol codes.

Get the Advanced Query Syntax (AQS) cord for the device

Generate an avant-garde query string (AQS) that contains identification information about the device that y'all want to find. You can generate the string either past specifying the vendor/product IDs, device interface GUID, or by the device form.

  • If you desire to provide the vendor ID/production ID or the device interface GUID, call whatsoever overload of GetDeviceSelector.

    In the example of the SuperMUTT device, GetDeviceSelector retrieves an AQS string similar to this string:

    "System.Devices.InterfaceClassGuid:="{DEE824EF-729B-4A0E-9C14-B7117D33A817}" AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True AND Organisation.DeviceInterface.WinUsb.UsbVendorId:=1118 AND System.DeviceInterface.WinUsb.UsbProductId:=61441"

    Note  Notice that the device interface GUID that appears in the string is not the ane you specified. That GUID is the bodily device interface GUID registered past Winusb.sys for UWP apps.

  • If you know the device class of the device or its course, bracket, and protocol codes, phone call GetDeviceClassSelector to generate the AQS string.

    Create a UsbDeviceClass object by specifying ClassCode, SubclassCode, and ProtocolCode property values. Alternatively, if you know the device class of the device, you can call the constructor by specifying a particular UsbDeviceClasses belongings.

Finding the device—The basic mode

This is the simplest way to find a USB device. For details, run into Quickstart: enumerating commonly used devices.

  1. Pass the retrieved AQS string to FindAllAsync. The telephone call retrieves a DeviceInformationCollection object.
  2. Loop through the collection. Each iteration gets a DeviceInformation object.
  3. Get the DeviceInformation.Id holding value. The cord value is the device instance path. For example, "\\\\?\\USB#VID_045E&PID_078F#half-dozen&1b8ff026&0&5#{dee824ef-729b-4a0e-9c14-b7117d33a817}".
  4. Call FromIdAsync past passing the device example string and get the UsbDevice object. You tin can then use the UsbDevice object to perform other operations, such equally sending a control transfer. When the app has finished using the UsbDevice object, the app must release information technology past calling Shut. Note  When UWP app suspends, the device is closed automatically. To avoid using a stale handle for futurity operations, the app must released the UsbDevice reference.
                              private async void OpenDevice()     {         UInt32 vid = 0x045E;         UInt32 pid = 0x0611;          string aqs = UsbDevice.GetDeviceSelector(vid, pid);          var myDevices = look Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(aqs);          try         {             usbDevice = look UsbDevice.FromIdAsync(myDevices[0].Id);         }         catch (Exception exception)         {             ShowStatus(exception.Message.ToString());         }         finally                 {             ShowStatus("Opened device for communication.");         }      }                          

Find the device—using DeviceWatcher

Alternatively, you can enumerate devices dynamically. Then, your app can receive notification if devices are added or removed, or if device properties change. For more information, run into How to get notifications if devices are added, removed, or inverse.

A DeviceWatcher object enables an app to dynamically detect devices as they get added and removed from the system.

  1. Create a DeviceWatcher object to detect when the device is added to or removed from the system. You must create the object by calling CreateWatcher and specifying the AQS string.

  2. Implement and register handlers for Added and Removed events on the DeviceWatcher object. Those upshot handlers are invoked when devices (with the same identification data) are added or removed from the system.

  3. Starting time and finish the DeviceWatcher object.

    The app must start the DeviceWatcher object by calling Start so that it can start detecting devices as they are added or removed from the system. Conversely, the app must stop the DeviceWatcher past calling Stop, when it's no longer necessary to detect devices. The sample has two buttons that allows the user to start and stop DeviceWatcher.

This code example shows how to create and starting time a device watcher to look for instances of the SuperMUTT device.

              void CreateSuperMuttDeviceWatcher(void) {     UInt32 vid = 0x045E;     UInt32 pid = 0x0611;      string aqs = UsbDevice.GetDeviceSelector(vid, pid);            var superMuttWatcher = DeviceInformation.CreateWatcher(aqs);        superMuttWatcher.Added += new TypedEventHandler<DeviceWatcher, DeviceInformation>                               (this.OnDeviceAdded);      superMuttWatcher.Removed += new TypedEventHandler<DeviceWatcher, DeviceInformationUpdate>                             (this.OnDeviceRemoved);      superMuttWatcher.Start();  }                          

Open the device

To open up the device, the app must start an asynchronous operation by calling the static method FromIdAsync and passing the device instance path (obtained from DeviceInformation.Id). That result of that operation obtain is a UsbDevice object, which is used for future communication with the device, such every bit performing data transfers.

After you are finished using the UsbDevice object, you lot must release it. By releasing the object, all pending data transfers are canceled. The completion callback routines for those operations are even so invoked with canceled error or the operation completed.

C++ apps must release the reference by using the delete keyword. C#/VB apps must telephone call the UsbDevice.Dispose method. JavaScript apps must call UsbDevice.Close.

The FromIdAsync fails if the device is in utilize or cannot be found.