Compartir a través de


Cómo conectarse a un dispositivo USB (aplicación para UWP)

En Windows, puedes escribir una aplicación para UWP que interactúe con un dispositivo USB.

En este artículo se describe:

  • Uso del objeto DeviceWatcher para detectar dispositivos
  • Cómo abrir el dispositivo para la comunicación
  • Cómo cerrar el dispositivo cuando haya terminado de usarlo

API importantes

Al escribir una aplicación para UWP que interactúe con un dispositivo USB, la aplicación puede enviar comandos de control, obtener información del dispositivo y leer y escribir datos en puntos de conexión masivos e interrumpirlos. Para poder hacer todo eso, debe encontrar el dispositivo y establecer la conexión.

Antes de empezar

  • Este es el primer tema de una serie. Antes de comenzar este tutorial, debe haber creado un proyecto básico de Visual Studio que pueda ampliar en este tutorial. Lee Introducción a las aplicaciones para UWP para obtener más información.
  • Los ejemplos de código se basan en el ejemplo CustomUsbDeviceAccess. Puede descargar el ejemplo completo desde esta página de la galería de códigos.
  • El dispositivo USB usado en el tutorial es el dispositivo SuperMUTT.
  • Para usar el espacio de nombres Windows.Devices.Usb para escribir una aplicación de Windows que interactúe con un dispositivo USB, el dispositivo debe tener cargado el controlador de Winusb.sys como controlador de función. Microsoft proporciona Winusb.sys y se incluye con Windows en la carpeta \Windows\System32\drivers .

Diagrama de flujo: Búsqueda del dispositivo

Para conectarse a un dispositivo USB, primero debe encontrar el dispositivo en función de varios patrones de detección y, a continuación, conectarse a él:

  • Conéctese a cualquier dispositivo USB con un GUID de interfaz de dispositivo específico.
  • Conéctese a un dispositivo USB con un identificador de proveedor y un identificador de producto concretos y que tenga un GUID de interfaz de dispositivo específico.
  • Conéctese a un dispositivo USB con un id. de proveedor y un identificador de producto concretos sin conocer el GUID de la interfaz del dispositivo.
  • Conéctese a un dispositivo USB que tenga una clase de dispositivo conocida.

Detección de dispositivos usb.

Conceptos clave

¿Qué es un GUID de interfaz de dispositivo?

Un controlador de modelo de kernel, durante su inicialización, registra y expone un GUID denominado GUID de interfaz de dispositivo. Normalmente, la aplicación usa el GUID expuesto para buscar el controlador asociado y su dispositivo y, a continuación, abrir un identificador para el dispositivo. El identificador recuperado se usa para las operaciones de lectura y escritura posteriores.

Sin embargo, en el caso de Winusb.sys, en lugar del controlador que expone el GUID de la interfaz de dispositivo, se puede proporcionar de una de estas dos maneras:

  • En los descriptores de MS OS del dispositivo. El fabricante del dispositivo establece DeviceInterfaceGUID como una propiedad personalizada en el descriptor de propiedades extendidas del dispositivo. Para obtener más información, consulte el documento "Descriptores de propiedades extendidas" en Descriptores del sistema operativo de Microsoft.
  • Si instaló Winusb.sys manualmente a través de un INF personalizado, INF registró un GUID en INF. Consulte Instalación de WinUSB (Winusb.sys).

Si se encuentra un GUID de interfaz de dispositivo para el dispositivo, la aplicación para UWP puede encontrar todos los dispositivos que coincidan con ese GUID de interfaz de dispositivo.

¿Cómo se muestra la identificación del dispositivo USB en Windows?

Cada dispositivo USB debe tener dos partes de información: id. de proveedor e id. de producto.

USB-IF asigna esos identificadores y el fabricante del dispositivo debe exponerlos en el dispositivo. ¿Cómo puede obtener esa información?

  • Incluso cuando el dispositivo no tiene cargado un controlador de dispositivo, es decir, Windows lo detecta como un "Dispositivo desconocido", todavía puede ver los identificadores en el Administrador de dispositivos en el valor de la propiedad Id. de hardware. Ese valor es una combinación de esos dos identificadores. Por ejemplo, para el dispositivo SuperMUTT, el identificador de hardware es "USB\VID_045E&PID_F001"; el identificador de proveedor es "0x045E" y el identificador de producto es "0xF001".

  • Si hay un INF para el dispositivo, obtenga esa cadena de la sección Modelos .

  • Puede inspeccionar varias configuraciones del Registro. La manera más fácil es ver el

    id. de <hardware deHKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\USB\>

    Para obtener más información, consulte Entradas del Registro de dispositivos USB.

  • El manifiesto de la aplicación usa el identificador de hardware para identificar el dispositivo.

    <Id. de dispositivo="vidpid:045e f001">

La aplicación para UWP puede encontrar todos los dispositivos que coincidan con un proveedor y identificadores de producto específicos. Puede restringir los resultados de búsqueda especificando el GUID de la interfaz del dispositivo.

¿Qué son las clases de dispositivo USB?

La mayoría de los dispositivos USB cumplen las especificaciones de clase de dispositivo aprobadas por USB-IF. Al usar esas especificaciones, los dispositivos de naturaleza similar pueden mostrar su funcionalidad de forma estándar. La mayor ventaja de este enfoque es que el dispositivo puede usar un controlador de clase integrada proporcionado por Microsoft o el controlador de Winusb.sys genérico.

Es posible que algunos dispositivos no sigan una especificación USB-IF. En su lugar, exponen la funcionalidad definida por el proveedor . Para estos dispositivos, el proveedor debe proporcionar el controlador de dispositivo o Winusb.sys se puede usar.

Tanto si un dispositivo está definido por el proveedor como si se ajusta a una clase de dispositivo, debe describir esta información relacionada con la clase de dispositivo:

  • Código de clase: indica la clase de dispositivo a la que pertenece el dispositivo.
  • Código de subclase: dentro de la clase de dispositivo, indica la subclase del dispositivo.
  • Código de protocolo: el protocolo que usa el dispositivo.

Por ejemplo, el dispositivo SuperMUTT es un dispositivo definido por el proveedor y esa información se indica mediante el código de clase es FF. Si el dispositivo muestra el código de clase como FEh, el código de subclase como 02h y el código de protocolo 00h, puede concluir que el dispositivo es un dispositivo de puente IrDA compatible con la clase. La aplicación para UWP puede comunicarse con dispositivos que pertenecen a estas clases de dispositivo:

  • ActiveSync
  • CdcControl
  • DeviceFirmwareUpdate
  • Irda
  • Medición
  • PalmSync
  • PersonalHealthcare
  • Física
  • VendorSpecific

La aplicación para UWP puede encontrar todos los dispositivos que coincidan con un conjunto específico de códigos de clase, subclase y protocolo.

Obtención de la cadena de sintaxis de consulta avanzada (AQS) para el dispositivo

Genere una cadena de consulta avanzada (AQS) que contenga información de identificación sobre el dispositivo que desea detectar. Para generar la cadena, especifique los identificadores de proveedor o producto, el GUID de la interfaz de dispositivo o la clase de dispositivo.

  • Si quiere proporcionar el identificador de proveedor o el identificador de producto o el GUID de la interfaz de dispositivo, llame a cualquier sobrecarga de GetDeviceSelector.

    En el ejemplo del dispositivo SuperMUTT, GetDeviceSelector recupera una cadena de AQS similar a esta cadena:

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

    Nota Observe que el GUID de la interfaz de dispositivo que aparece en la cadena no es el especificado. Ese GUID es el GUID de interfaz de dispositivo real registrado por Winusb.sys para aplicaciones para UWP.

  • Si conoce la clase de dispositivo del dispositivo o sus códigos de clase, subclase y protocolo, llame a GetDeviceClassSelector para generar la cadena de AQS.

    Cree un objeto UsbDeviceClass especificando los valores de propiedad ClassCode, SubclassCode y ProtocolCode . Como alternativa, si conoce la clase de dispositivo del dispositivo, puede llamar al constructor especificando una propiedad UsbDeviceClasses determinada.

Búsqueda del dispositivo: la manera básica

Esta es la manera más sencilla de encontrar un dispositivo USB. Para más información, consulte Inicio rápido: enumeración de dispositivos usados habitualmente.

  1. Pase la cadena de AQS recuperada a FindAllAsync. La llamada recupera un objeto DeviceInformationCollection .
  2. Recorra la colección. Cada iteración obtiene un objeto DeviceInformation .
  3. Obtenga el valor de la propiedad DeviceInformation.Id . El valor de cadena es la ruta de acceso de la instancia del dispositivo. Por ejemplo, "\\\USB#VID_045E&PID_078F#6&1b8ff026&0&5#{dee824ef-729b-4a0e-9c14-b7117d33a817}".
  4. Llame a FromIdAsync pasando la cadena de instancia del dispositivo y obtenga el objeto UsbDevice . A continuación, puede usar el objeto UsbDevice para realizar otras operaciones, como enviar una transferencia de control. Cuando la aplicación haya terminado de usar el objeto UsbDevice , la aplicación debe liberarla llamando a Close. Nota Cuando se suspende la aplicación para UWP, el dispositivo se cierra automáticamente. Para evitar el uso de un identificador obsoleto para futuras operaciones, la aplicación debe liberar la referencia de UsbDevice .
    private async void OpenDevice()
    {
        UInt32 vid = 0x045E;
        UInt32 pid = 0x0611;

        string aqs = UsbDevice.GetDeviceSelector(vid, pid);

        var myDevices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(aqs);

        try
        {
            usbDevice = await UsbDevice.FromIdAsync(myDevices[0].Id);
        }
        catch (Exception exception)
        {
            ShowStatus(exception.Message.ToString());
        }
        finally
        {
            ShowStatus("Opened device for communication.");
        }

    }

Búsqueda del dispositivo mediante DeviceWatcher

Como alternativa, puede enumerar los dispositivos dinámicamente. A continuación, la aplicación puede recibir notificaciones si los dispositivos se agregan o quitan, o si cambian las propiedades del dispositivo. Para obtener más información, consulte Cómo obtener notificaciones si se agregan, quitan o cambian los dispositivos.

Un objeto DeviceWatcher permite a una aplicación detectar dinámicamente los dispositivos a medida que se agregan y quitan del sistema.

  1. Cree un objeto DeviceWatcher para detectar cuándo se agrega o quita el dispositivo del sistema. Debe crear el objeto llamando a CreateWatcher y especificando la cadena AQS.

  2. Implemente y registre controladores para eventos agregados y eliminados en el objeto DeviceWatcher . Estos controladores de eventos se invocan cuando los dispositivos (con la misma información de identificación) se agregan o quitan del sistema.

  3. Inicie y detenga el objeto DeviceWatcher .

    La aplicación debe iniciar el objeto DeviceWatcher llamando a Start para que pueda empezar a detectar dispositivos a medida que se agregan o quitan del sistema. Por el contrario, la aplicación debe detener DeviceWatcher llamando a Stop, cuando ya no es necesario detectar dispositivos. El ejemplo tiene dos botones que permiten al usuario iniciar y detener DeviceWatcher.

En este ejemplo de código se muestra cómo crear e iniciar un monitor de dispositivo para buscar instancias del dispositivo SuperMUTT.

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();
 }

Abrir el dispositivo

Para abrir el dispositivo, la aplicación debe iniciar una operación asincrónica llamando al método estático FromIdAsync y pasando la ruta de acceso de la instancia del dispositivo (obtenida de DeviceInformation.Id). Ese resultado de esa operación obtener es un objeto UsbDevice , que se usa para la comunicación futura con el dispositivo, como la realización de transferencias de datos.

Una vez que haya terminado de usar el objeto UsbDevice , debe liberarlo. Al liberar el objeto, se cancelan todas las transferencias de datos pendientes. Las rutinas de devolución de llamada de finalización para esas operaciones se siguen invocando con un error cancelado o la operación completada.

Las aplicaciones de C++ deben liberar la referencia mediante la palabra clave delete . Las aplicaciones de C#/VB deben llamar al método UsbDevice.Dispose . Las aplicaciones de JavaScript deben llamar a UsbDevice.Close.

Se produce un error en FromIdAsync si el dispositivo está en uso o no se encuentra.