5 Answers 5
there's a .net library for that: SharpUSBLib
http://www.icsharpcode.net/OpenSource/SharpUSBLib/default.aspx
answered Nov 24, 2010 at 13:59
Ali Tarhini
5,3686 gold badges45 silver badges66 bronze badges
Sign up to request clarification or add additional context in comments.
Comments
There are many libraries that achieve the job. Here is sample code for three platforms from Usb.Net (https://github.com/MelbourneDeveloper/Device.Net)
Windows (WinUSB)
public override Task InitializeAsync()
{
Dispose();
int errorCode;
if (string.IsNullOrEmpty(DeviceId))
{
throw new WindowsException($"{nameof(DeviceDefinition)} must be specified before {nameof(InitializeAsync)} can be called.");
}
_DeviceHandle = APICalls.CreateFile(DeviceId, (APICalls.GenericWrite | APICalls.GenericRead), APICalls.FileShareRead | APICalls.FileShareWrite, IntPtr.Zero, APICalls.OpenExisting, APICalls.FileAttributeNormal | APICalls.FileFlagOverlapped, IntPtr.Zero);
if (_DeviceHandle.IsInvalid)
{
//TODO: is error code useful here?
errorCode = Marshal.GetLastWin32Error();
if (errorCode > 0) throw new Exception($"Device handle no good. Error code: {errorCode}");
}
var isSuccess = WinUsbApiCalls.WinUsb_Initialize(_DeviceHandle, out var defaultInterfaceHandle);
HandleError(isSuccess, "Couldn't initialize device");
var bufferLength = (uint)Marshal.SizeOf(typeof(USB_DEVICE_DESCRIPTOR));
isSuccess = WinUsbApiCalls.WinUsb_GetDescriptor(defaultInterfaceHandle, WinUsbApiCalls.DEFAULT_DESCRIPTOR_TYPE, 0, 0, out _UsbDeviceDescriptor, bufferLength, out var lengthTransferred);
HandleError(isSuccess, "Couldn't get device descriptor");
byte i = 0;
//Get the first (default) interface
var defaultInterface = GetInterface(defaultInterfaceHandle);
_UsbInterfaces.Add(defaultInterface);
while (true)
{
isSuccess = WinUsbApiCalls.WinUsb_GetAssociatedInterface(defaultInterfaceHandle, i, out var interfacePointer);
if (!isSuccess)
{
errorCode = Marshal.GetLastWin32Error();
if (errorCode == APICalls.ERROR_NO_MORE_ITEMS) break;
throw new Exception($"Could not enumerate interfaces for device {DeviceId}. Error code: { errorCode}");
}
var associatedInterface = GetInterface(interfacePointer);
_UsbInterfaces.Add(associatedInterface);
i++;
}
IsInitialized = true;
RaiseConnected();
return Task.CompletedTask;
}
public override async Task<byte[]> ReadAsync()
{
return await Task.Run(() =>
{
var bytes = new byte[ReadBufferSize];
//TODO: Allow for different interfaces and pipes...
var isSuccess = WinUsbApiCalls.WinUsb_ReadPipe(_DefaultUsbInterface.Handle, _DefaultUsbInterface.ReadPipe.WINUSB_PIPE_INFORMATION.PipeId, bytes, ReadBufferSize, out var bytesRead, IntPtr.Zero);
HandleError(isSuccess, "Couldn't read data");
Tracer?.Trace(false, bytes);
return bytes;
});
}
public override async Task WriteAsync(byte[] data)
{
await Task.Run(() =>
{
if (data.Length > WriteBufferSize)
{
throw new Exception($"Data is longer than {WriteBufferSize} bytes which is the device's max buffer size.");
}
//TODO: Allow for different interfaces and pipes...
var isSuccess = WinUsbApiCalls.WinUsb_WritePipe(_DefaultUsbInterface.Handle, _DefaultUsbInterface.WritePipe.WINUSB_PIPE_INFORMATION.PipeId, data, (uint)data.Length, out var bytesWritten, IntPtr.Zero);
HandleError(isSuccess, "Couldn't write data");
Tracer?.Trace(true, data);
});
}
UWP
public override async Task InitializeAsync()
{
await GetDevice(DeviceId);
if (_ConnectedDevice != null)
{
var usbInterface = _ConnectedDevice.Configuration.UsbInterfaces.FirstOrDefault();
if (usbInterface == null)
{
_ConnectedDevice.Dispose();
throw new Exception("There was no Usb Interface found for the device.");
}
var interruptPipe = usbInterface.InterruptInPipes.FirstOrDefault();
if (interruptPipe == null)
{
throw new Exception("There was no interrupt pipe found on the interface");
}
interruptPipe.DataReceived += InterruptPipe_DataReceived;
RaiseConnected();
}
else
{
throw new Exception($"Could not connect to device with Device Id {DeviceId}. Check that the package manifest has been configured to allow this device.");
}
}
public override async Task WriteAsync(byte[] bytes)
{
var bufferToSend = bytes.AsBuffer();
var usbInterface = _ConnectedDevice.Configuration.UsbInterfaces.FirstOrDefault();
var outPipe = usbInterface.InterruptOutPipes.FirstOrDefault();
await outPipe.OutputStream.WriteAsync(bufferToSend);
Tracer?.Trace(false, bytes);
}
public override async Task<byte[]> ReadAsync()
{
if (_IsReading)
{
throw new Exception("Reentry");
}
lock (_Chunks)
{
if (_Chunks.Count > 0)
{
var retVal = _Chunks[0];
Tracer?.Trace(false, retVal);
_Chunks.RemoveAt(0);
return retVal;
}
}
_IsReading = true;
_TaskCompletionSource = new TaskCompletionSource<byte[]>();
return await _TaskCompletionSource.Task;
}
Android
public async Task InitializeAsync()
{
//TODO: Use a semaphore lock here
if (_IsInitializing)
{
return;
}
_IsInitializing = true;
try
{
//TODO:
//Dispose();
var isPermissionGranted = await RequestPermissionAsync();
if (!isPermissionGranted.HasValue)
{
throw new Exception("User did not respond to permission request");
}
if (!isPermissionGranted.Value)
{
throw new Exception("The user did not give the permission to access the device");
}
var usbInterface = _UsbDevice.GetInterface(0);
//TODO: This selection stuff needs to be moved up higher. The constructor should take these arguments
for (var i = 0; i < usbInterface.EndpointCount; i++)
{
var ep = usbInterface.GetEndpoint(i);
if (_ReadEndpoint == null && ep.Type == UsbAddressing.XferInterrupt && ep.Address == (UsbAddressing)129)
{
_ReadEndpoint = ep;
continue;
}
if (_WriteEndpoint == null && ep.Type == UsbAddressing.XferInterrupt && (ep.Address == (UsbAddressing)1 || ep.Address == (UsbAddressing)2))
{
_WriteEndpoint = ep;
}
}
//TODO: This is a bit of a guess. It only kicks in if the previous code fails. This needs to be reworked for different devices
if (_ReadEndpoint == null)
{
_ReadEndpoint = usbInterface.GetEndpoint(0);
}
if (_WriteEndpoint == null)
{
_WriteEndpoint = usbInterface.GetEndpoint(1);
}
if (_ReadEndpoint.MaxPacketSize != ReadBufferLength)
{
throw new Exception("Wrong packet size for read endpoint");
}
if (_WriteEndpoint.MaxPacketSize != ReadBufferLength)
{
throw new Exception("Wrong packet size for write endpoint");
}
_UsbDeviceConnection = UsbManager.OpenDevice(_UsbDevice);
if (_UsbDeviceConnection == null)
{
throw new Exception("could not open connection");
}
if (!_UsbDeviceConnection.ClaimInterface(usbInterface, true))
{
throw new Exception("could not claim interface");
}
Logger.Log("Hid device initialized. About to tell everyone.", null, LogSection);
IsInitialized = true;
RaiseConnected();
return;
}
catch (Exception ex)
{
Logger.Log("Error initializing Hid Device", ex, LogSection);
}
_IsInitializing = false;
}
public override async Task<byte[]> ReadAsync()
{
try
{
var byteBuffer = ByteBuffer.Allocate(ReadBufferLength);
var request = new UsbRequest();
request.Initialize(_UsbDeviceConnection, _ReadEndpoint);
request.Queue(byteBuffer, ReadBufferLength);
await _UsbDeviceConnection.RequestWaitAsync();
var buffers = new byte[ReadBufferLength];
byteBuffer.Rewind();
for (var i = 0; i < ReadBufferLength; i++)
{
buffers[i] = (byte)byteBuffer.Get();
}
//Marshal.Copy(byteBuffer.GetDirectBufferAddress(), buffers, 0, ReadBufferLength);
Tracer?.Trace(false, buffers);
return buffers;
}
catch (Exception ex)
{
Logger.Log(Helpers.ReadErrorMessage, ex, LogSection);
throw new IOException(Helpers.ReadErrorMessage, ex);
}
}
public override async Task WriteAsync(byte[] data)
{
try
{
var request = new UsbRequest();
request.Initialize(_UsbDeviceConnection, _WriteEndpoint);
var byteBuffer = ByteBuffer.Wrap(data);
Tracer?.Trace(true, data);
request.Queue(byteBuffer, data.Length);
await _UsbDeviceConnection.RequestWaitAsync();
}
catch (Exception ex)
{
Logger.Log(Helpers.WriteErrorMessage, ex, LogSection);
throw new IOException(Helpers.WriteErrorMessage, ex);
}
}
answered Dec 28, 2018 at 6:32
Christian Findlay
7,8605 gold badges65 silver badges114 bronze badges
Comments
this site definitely help u...
http://libusbdotnet.sourceforge.net
it contains a class library and some sample codes release on 2010
answered Sep 24, 2012 at 6:25
saeed
2,5172 gold badges25 silver badges40 bronze badges
Comments
lang-cs