Trabajando con dispositivos USB en .NET

Usando .Net (C #), ¿cómo puedes trabajar con dispositivos USB?

¿Cómo puede detectar eventos USB (conexiones / desconexiones) y cómo se comunica con los dispositivos (lectura / escritura)?

¿Hay una solución .Net nativa para hacer esto?

No hay una solución nativa (por ejemplo, bibliotecas del sistema) para esto. Esa es la razón por la que SharpUSBLib existe como lo menciona Moobaa .

Si desea instalar su propio controlador para dispositivos USB, puede consultar la clase SerialPort de System.IO.Ports .

Intenté usar SharpUSBLib y estropeó mi computadora (necesitaba una restauración del sistema). Sucedió a un compañero de trabajo en el mismo proyecto también.

He encontrado una alternativa en LibUSBDotNet: http://sourceforge.net/projects/libusbdotnet. Todavía no la he usado demasiado pero parece estar bien actualizada (a diferencia de Sharp).

EDITAR: a partir de mediados de febrero de 2017, LibUSBDotNet se actualizó hace aproximadamente 2 semanas. Mientras tanto, SharpUSBLib no se ha actualizado desde 2004.

La biblioteca USB #usblib para .NET

Utilicé el siguiente código para detectar cuándo se enchufaron y desenchufaron los dispositivos USB de mi computadora:

class USBControl : IDisposable { // used for monitoring plugging and unplugging of USB devices. private ManagementEventWatcher watcherAttach; private ManagementEventWatcher watcherRemove; public USBControl() { // Add USB plugged event watching watcherAttach = new ManagementEventWatcher(); //var queryAttach = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2"); watcherAttach.EventArrived += new EventArrivedEventHandler(watcher_EventArrived); watcherAttach.Query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2"); watcherAttach.Start(); // Add USB unplugged event watching watcherRemove = new ManagementEventWatcher(); //var queryRemove = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 3"); watcherRemove.EventArrived += new EventArrivedEventHandler(watcher_EventRemoved); watcherRemove.Query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 3"); watcherRemove.Start(); } ///  /// Used to dispose of the USB device watchers when the USBControl class is disposed of. ///  public void Dispose() { watcherAttach.Stop(); watcherRemove.Stop(); //Thread.Sleep(1000); watcherAttach.Dispose(); watcherRemove.Dispose(); //Thread.Sleep(1000); } void watcher_EventArrived(object sender, EventArrivedEventArgs e) { Debug.WriteLine("watcher_EventArrived"); } void watcher_EventRemoved(object sender, EventArrivedEventArgs e) { Debug.WriteLine("watcher_EventRemoved"); } ~USBControl() { this.Dispose(); } } 

Debe asegurarse de llamar al método Dispose () al cerrar su aplicación. De lo contrario, recibirá un error de objeto COM en tiempo de ejecución al cerrar.

Recomendaría LibUSBDotNet , la biblioteca que he estado usando durante 2 años. Si tiene que trabajar con un dispositivo USB (enviar solicitudes, procesar respuestas), esta biblioteca fue la mejor solución que pude encontrar.

Pros:

  • Tiene todos los métodos que necesita para trabajar en modo sincronización o asíncrono.
  • Código fuente proporcionado
  • Suficientes muestras para comenzar a usarlo de inmediato.

Contras:

  • Documentación deficiente (es un problema común para los proyectos de código abierto). Básicamente, puede encontrar una descripción común de los métodos en el archivo de ayuda de CHM, y eso es todo. Pero todavía encuentro que las muestras proporcionadas y el código fuente son suficientes para la encoding. A veces veo un comportamiento extraño y quiero saber por qué se implementó de esta manera y no puedo obtener ni una pista …
  • Parece sin apoyo más. La última versión se publicó en octubre de 2010. Y a veces es difícil obtener respuestas.

Hay un tutorial sobre cómo obtener la biblioteca SharpUSBLib y los controladores HID que trabajan con C # aquí:

http://www.developerfusion.com/article/84338/making-usb-c-friendly/

Hay un juego de herramientas genérico WinDriver para escribir controladores USB en modo de usuario que también admite # .NET

Si tiene software de National Instruments en su PC, puede crear un controlador USB usando su “Asistente de controladores NI-VISA” .

Pasos para crear el controlador USB: http://www.ni.com/tutorial/4478/en/

Una vez que haya creado el controlador, podrá escribir y leer los bytes en cualquier dispositivo USB.

Asegúrese de que el controlador sea visto por Windows en el Administrador de dispositivos:

enter image description here

C # Code:

  using NationalInstruments.VisaNS; #region UsbRaw ///  /// Class to communicate with USB Devices using the UsbRaw Class of National Instruments ///  public class UsbRaw { private NationalInstruments.VisaNS.UsbRaw usbRaw; private List DataReceived = new List(); ///  /// Initialize the USB Device to interact with ///  /// In this format: "USB0::0x1448::0x8CA0::NI-VISA-30004::RAW". Use the NI-VISA Driver Wizard from Start»All Programs»National Instruments»VISA»Driver Wizard to create the USB Driver for the device you need to talk to. public UsbRaw(string ResourseName) { usbRaw = new NationalInstruments.VisaNS.UsbRaw(ResourseName, AccessModes.NoLock, 10000, false); usbRaw.UsbInterrupt += new UsbRawInterruptEventHandler(OnUSBInterrupt); usbRaw.EnableEvent(UsbRawEventType.UsbInterrupt, EventMechanism.Handler); } ///  /// Clears a USB Device from any previous commands ///  public void Clear() { usbRaw.Clear(); } ///  /// Writes Bytes to the USB Device ///  /// USB Bulk Out Pipe attribute to send the data to. For example: If you see on the Bus Hound sniffer tool that data is coming out from something like 28.4 (Device column), this means that the USB is using Endpoint 4 (Number after the dot) /// Data to send to the USB device public void Write(short EndPoint, byte[] BytesToSend) { usbRaw.BulkOutPipe = EndPoint; usbRaw.Write(BytesToSend); // Write to USB } ///  /// Reads bytes from a USB Device ///  /// Bytes Read public byte[] Read() { usbRaw.ReadByteArray(); // This fires the UsbRawInterruptEventHandler byte[] rxBytes = DataReceived.ToArray(); // Collects the data received return rxBytes; } ///  /// This is used to get the data received by the USB device ///  ///  ///  private void OnUSBInterrupt(object sender, UsbRawInterruptEventArgs e) { try { DataReceived.Clear(); // Clear previous data received DataReceived.AddRange(e.DataBuffer); } catch (Exception exp) { string errorMsg = "Error: " + exp.Message; DataReceived.AddRange(ASCIIEncoding.ASCII.GetBytes(errorMsg)); } } ///  /// Use this function to clean up the UsbRaw class ///  public void Dispose() { usbRaw.DisableEvent(UsbRawEventType.UsbInterrupt, EventMechanism.Handler); if (usbRaw != null) { usbRaw.Dispose(); } } } #endregion UsbRaw 

Uso:

 UsbRaw usbRaw = new UsbRaw("USB0::0x1448::0x8CA0::NI-VISA-30004::RAW"); byte[] sendData = new byte[] { 0x53, 0x4c, 0x56 }; usbRaw.Write(4, sendData); // Write bytes to the USB Device byte[] readData = usbRaw.Read(); // Read bytes from the USB Device usbRaw.Dispose(); 

Espero que esto ayude a alguien.

La mayoría de los chipsets USB vienen con controladores. Silicon Labs tiene uno.

He obtenido una interfaz para un Teensy que funciona bastante bien, usando este artículo

Probé varias de estas sugerencias sin suerte. Terminé escribiendo una solución de trabajo usando Java y la biblioteca hid4java . Como aplicación de consola, puedo pagarlo desde C # utilizando Process.Start() , pasando parámetros y leyendo respuestas. Esto proporciona E / S HID básica pero sin eventos de conexión / desconexión. Para eso necesitaría reescribirlo para ejecutarlo como daemon / servicio y usar pipes con nombre o algún otro transporte de servidor / cliente. Por ahora, es suficiente para hacer el trabajo, ya que la biblioteca hi4java “simplemente funciona”.