GithubHelp home page GithubHelp logo

mikeobrien / hidlibrary Goto Github PK

View Code? Open in Web Editor NEW
563.0 52.0 223.0 15.31 MB

This library enables you to enumerate and communicate with Hid compatible USB devices in .NET.

License: MIT License

C# 57.14% F# 15.02% HTML 27.83%

hidlibrary's Introduction

NOTE: Support is VERY limited for this library. It is almost impossible to troubleshoot issues with so many devices and configurations. The community may be able to offer some assistance but you will largely be on your own. If you submit an issue, please include a relevant code snippet and details about your operating system, .NET version and device. Pull requests are welcome and appreciated.

Hid Library

Nuget TeamCity Build Status

This library enables you to enumerate and communicate with Hid compatible USB devices in .NET. It offers synchronous and asynchronous read and write functionality as well as notification of insertion and removal of a device. This library works on x86 and x64.

Installation

PM> Install-Package hidlibrary

Developers

Mike O'Brien Austin Mullins
Mike O'Brien Austin Mullins

Contributors

Benjamin Wegman jwelch222 Thomas Hammer juliansiebert George Hahn
Benjamin Wegman jwelch222 Thomas Hammer juliansiebert George Hahn
Rick van Lieshout Paul Trandem Neil Thiessen intrueder Bruno Juchli
Rick van Lieshout Paul Trandem Neil Thiessen intrueder Bruno Juchli
sblakemore J.C Marek Roszko Bill Prescott Ananth Racherla
sblakemore J.C Marek Roszko Bill Prescott Ananth Racherla

Props

Thanks to JetBrains for providing OSS licenses for R# and dotTrace!

Resources

If your interested in HID development here are a few invaluable resources:

  1. Jan Axelson's USB Hid Programming Page - Excellent resource for USB Hid development. Full code samples in a number of different languages demonstrate how to use the Windows setup and Hid API.
  2. Jan Axelson's book 'USB Complete' - Jan Axelson's guide to USB programming. Very good covereage of Hid. Must read for anyone new to Hid programming.

hidlibrary's People

Contributors

amullins83 avatar ananth-racherla avatar bprescott avatar brunojuchli avatar hazzard17h avatar jnm2 avatar juliansiebert avatar jw834ksj43 avatar marekr avatar mikeobrien avatar mjmatthiesen avatar mutex666 avatar neilt6 avatar ptrandem avatar rvlieshout avatar sblakemore avatar thammer avatar w-michal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hidlibrary's Issues

WaitTimeOut persists

If a WaitTimeOut is triggered when reading a report then all subsequent attempts always result in a WaitTimeOut

example pseudo code:

device.OpenDevice(DeviceMode.Overlapped, DeviceMode.Overlapped, ShareMode.ShareRead | ShareMode.ShareWrite);

device.WriteReport(replyWithDataReport);
HidReport rpt1 = device.ReadReport(1000); // rpt1 read status is Success

device.WriteReport(noReplyReport);
HidReport rpt2 = device.ReadReport(1000); // rpt2 read status is WaitTimeOut

device.WriteReport(replyWithDataReport);
HidReport rpt3 = device.ReadReport(1000); // rpt3 read status is WaitTimeOut

Issue #29 broke Windows XP compability

Issue #29 which attempted to fix the closedevice block ended up breaking windows xp compability.

CancelIoEx does not exist in pre Windows Vista kernel32.dll and calling it will result in an exception that also gets surpressed by the library and appears as nothing is happening.

I modified the CloseDeviceIO function to avoid calling CancelIoEX for anything older than Vista. Not sure if theres a better way.

    private static void CloseDeviceIO(IntPtr handle)
    {
        if (System.Environment.OSVersion.Version.Major > 5)
        {
            NativeMethods.CancelIoEx(handle, IntPtr.Zero);
        }
        NativeMethods.CloseHandle(handle);
    }

Leak of memory with "write"

Good day all,
First, thanks Mike, for making available this library wich represents a really great work...

I am using a single "hiddevice.write" in a loop, and I found using the task manager of Windows that the memory used is increasing very fast... I have disabled all the calls to the library except one to be sure. Enabling and disabling this last call put in light the fact that it is the cause of the leak of memory.

here is the code of the loop:
byte[] bufferout = new byte[9];

    while (!aborting)
    {
        bufferout[0] = 0;
        bufferout[1] = 2;
        bufferout[3] = 3;
        bufferout[2] = 0X41;
        myDevice.Write(bufferout);
        Thread.Sleep(10);
    }

I am using Visual studio and C# under W7...

After some search in the source code, I found where is the problem:

public class HidDevices
{
private static Guid _hidClassGuid = Guid.Empty;

    public static bool IsConnected(string devicePath)
    {
        //return EnumerateHidDevices().Where(x => x == devicePath).Any(); <=== 
        return true;
    }

Once the line put in comment and the return forced to true, no more leak...

By advance, thanks...

Robert

Trying to get initial state of a Device

Hi,
I'm trying to use ReadReport(ReadReportCallback callback) to get the current state of an HID device, before any input was received from the Device.
My goal is to track after CHANGES of the device's data on every data I receive - so when the application starts - I need to get the data from the device immediately, I can't wait to the first input...

Any idea how do I do it?

Thanks,
Eyal

Poor Performance on Windows 10 v1511

The performance of one of my programs has completely tanked after installing the Windows 10 November Update. Tested on multiple computers in the office with the same result.

logitech gamepad sample

Hi,
sample cant detect product ID. I`ve done this to get it work:

_device = HidDevices.Enumerate(VendorId, 0xC21E).FirstOrDefault();

And then it throw exception:

  public PrecisionMessage(byte[] message)
        {
            if (message != null && message.Length == 4)
            {
                Array.Reverse(message);
                _message = BitConverter.ToUInt32(message, 0);
            }
            else throw new InvalidCastException("Cannot convert gamepad message to 32 bit integer.");
            _buttonsPressed = GetButtonsPressed(this);
        }
System.InvalidCastException was unhandled
  Message=Cannot convert gamepad message to 32 bit integer.
  Source=LogitechGamepad
  StackTrace:
       v LogitechGamepad.PrecisionMessage..ctor(Byte[] message) v C:\Users\Ivo\Desktop\mikeobrien-HidLibrary-d682227\src\Samples\LogitechGamepad\PrecisionMessage.cs:ล™รกdek 40
       v LogitechGamepad.MessageFactory.CreateMessage(Int32 productId, Byte[] messageData) v C:\Users\Ivo\Desktop\mikeobrien-HidLibrary-d682227\src\Samples\LogitechGamepad\MessageFactory.cs:ล™รกdek 12
       v LogitechGamepad.Program.OnReport(HidReport report) v C:\Users\Ivo\Desktop\mikeobrien-HidLibrary-d682227\src\Samples\LogitechGamepad\Program.cs:ล™รกdek 55
       v HidLibrary.HidDevice.EndReadReport(IAsyncResult ar) v C:\Users\Ivo\Desktop\mikeobrien-HidLibrary-d682227\src\Current\HidLibrary\HidDevice.cs:ล™รกdek 242
       v System.Runtime.Remoting.Messaging.AsyncResult.SyncProcessMessage(IMessage msg)
       v System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg, IMessageSink replySink)
       v System.Runtime.Remoting.Proxies.AgileAsyncWorkerItem.DoAsyncCall()
       v System.Runtime.Remoting.Proxies.AgileAsyncWorkerItem.ThreadPoolCallBack(Object o)
       v System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
       v System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       v System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
       v System.Threading.ThreadPoolWorkQueue.Dispatch()
       v System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
  InnerException: 

Windows 7, x64. Sorry if this is useless observation.

NativeMethods

I modified the "NativeMethods" class and removed unused classes and methods for better compatibility. This one passes the Visual Studio code analysis, too.

Maybe you want to use this version.

In some method calls "0" has to be replaced by "IntPtr.Zero". That's all.

using System;
using System.Runtime.InteropServices;

namespace HidLibrary
{
    public static class NativeMethods
    {
        internal const int FILE_FLAG_OVERLAPPED = 0x40000000;
        internal const short FILE_SHARE_READ = 0x1;
        internal const short FILE_SHARE_WRITE = 0x2;
        internal const uint GENERIC_READ = 0x80000000;
        internal const uint GENERIC_WRITE = 0x40000000;
        internal const int ACCESS_NONE = 0;
        internal const int INVALID_HANDLE_VALUE = -1;
        internal const short OPEN_EXISTING = 3;
        internal const int WAIT_TIMEOUT = 0x102;
        internal const uint WAIT_OBJECT_0 = 0;
        internal const uint WAIT_FAILED = 0xffffffff;

        internal const int WAIT_INFINITE = 0xffff;
        [StructLayout(LayoutKind.Sequential)]
        internal struct OVERLAPPED
        {
            public int Internal;
            public int InternalHigh;
            public int Offset;
            public int OffsetHigh;
            public int hEvent;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct SECURITY_ATTRIBUTES
        {
            public int nLength;
            public IntPtr lpSecurityDescriptor;
            public bool bInheritHandle;
        }

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static internal extern bool CancelIoEx(IntPtr hFile, IntPtr lpOverlapped);

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static internal extern bool CloseHandle(IntPtr hObject);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, BestFitMapping = false)]
        static internal extern IntPtr CreateEvent(ref SECURITY_ATTRIBUTES securityAttributes, int bManualReset, int bInitialState, string lpName);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false)]
        static internal extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, int dwShareMode, ref SECURITY_ATTRIBUTES lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static internal extern bool ReadFile(IntPtr hFile, [Out] byte[] lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, [In] ref System.Threading.NativeOverlapped lpOverlapped);

        [DllImport("kernel32.dll")]
        static internal extern uint WaitForSingleObject(IntPtr hHandle, int dwMilliseconds);

        [DllImport("kernel32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static internal extern bool WriteFile(IntPtr hFile, byte[] lpBuffer, uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten, [In] ref System.Threading.NativeOverlapped lpOverlapped);

        internal const int DBT_DEVICEARRIVAL = 0x8000;
        internal const int DBT_DEVICEREMOVECOMPLETE = 0x8004;
        internal const int DBT_DEVTYP_DEVICEINTERFACE = 5;
        internal const int DBT_DEVTYP_HANDLE = 6;
        internal const int DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 4;
        internal const int DEVICE_NOTIFY_SERVICE_HANDLE = 1;
        internal const int DEVICE_NOTIFY_WINDOW_HANDLE = 0;
        internal const int WM_DEVICECHANGE = 0x219;
        internal const short DIGCF_PRESENT = 0x2;
        internal const short DIGCF_DEVICEINTERFACE = 0x10;
        internal const int DIGCF_ALLCLASSES = 0x4;

        internal const int MAX_DEV_LEN = 1000;
        internal const int SPDRP_ADDRESS = 0x1c;
        internal const int SPDRP_BUSNUMBER = 0x15;
        internal const int SPDRP_BUSTYPEGUID = 0x13;
        internal const int SPDRP_CAPABILITIES = 0xf;
        internal const int SPDRP_CHARACTERISTICS = 0x1b;
        internal const int SPDRP_CLASS = 7;
        internal const int SPDRP_CLASSGUID = 8;
        internal const int SPDRP_COMPATIBLEIDS = 2;
        internal const int SPDRP_CONFIGFLAGS = 0xa;
        internal const int SPDRP_DEVICE_POWER_DATA = 0x1e;
        internal const int SPDRP_DEVICEDESC = 0;
        internal const int SPDRP_DEVTYPE = 0x19;
        internal const int SPDRP_DRIVER = 9;
        internal const int SPDRP_ENUMERATOR_NAME = 0x16;
        internal const int SPDRP_EXCLUSIVE = 0x1a;
        internal const int SPDRP_FRIENDLYNAME = 0xc;
        internal const int SPDRP_HARDWAREID = 1;
        internal const int SPDRP_LEGACYBUSTYPE = 0x14;
        internal const int SPDRP_LOCATION_INFORMATION = 0xd;
        internal const int SPDRP_LOWERFILTERS = 0x12;
        internal const int SPDRP_MFG = 0xb;
        internal const int SPDRP_PHYSICAL_DEVICE_OBJECT_NAME = 0xe;
        internal const int SPDRP_REMOVAL_POLICY = 0x1f;
        internal const int SPDRP_REMOVAL_POLICY_HW_DEFAULT = 0x20;
        internal const int SPDRP_REMOVAL_POLICY_OVERRIDE = 0x21;
        internal const int SPDRP_SECURITY = 0x17;
        internal const int SPDRP_SECURITY_SDS = 0x18;
        internal const int SPDRP_SERVICE = 4;
        internal const int SPDRP_UI_NUMBER = 0x10;
        internal const int SPDRP_UI_NUMBER_DESC_FORMAT = 0x1d;

        internal const int SPDRP_UPPERFILTERS = 0x11;

        [StructLayout(LayoutKind.Sequential)]
        internal struct SP_DEVICE_INTERFACE_DATA
        {
            internal int cbSize;
            internal System.Guid InterfaceClassGuid;
            internal int Flags;
            internal IntPtr Reserved;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct SP_DEVINFO_DATA
        {
            internal int cbSize;
            internal Guid ClassGuid;
            internal int DevInst;
            internal IntPtr Reserved;
        }

        [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
        internal struct SP_DEVICE_INTERFACE_DETAIL_DATA
        {
            internal int Size;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
            internal string DevicePath;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct DEVPROPKEY
        {
            public Guid fmtid;
            public ulong pid;
        }

        internal static DEVPROPKEY DEVPKEY_Device_BusReportedDeviceDesc =
            new DEVPROPKEY { fmtid = new Guid(0x540b947e, 0x8b40, 0x45bc, 0xa8, 0xa2, 0x6a, 0x0b, 0x89, 0x4c, 0xbd, 0xa2), pid = 4 };

        [DllImport("setupapi.dll", EntryPoint = "SetupDiGetDeviceRegistryProperty")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetupDiGetDeviceRegistryProperty(IntPtr deviceInfoSet, ref SP_DEVINFO_DATA deviceInfoData, int propertyVal, ref int propertyRegDataType, byte[] propertyBuffer, int propertyBufferSize, ref int requiredSize);

        [DllImport("setupapi.dll", EntryPoint = "SetupDiGetDevicePropertyW", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetupDiGetDeviceProperty(IntPtr deviceInfo, ref SP_DEVINFO_DATA deviceInfoData, ref DEVPROPKEY propkey, ref ulong propertyDataType, byte[] propertyBuffer, int propertyBufferSize, ref int requiredSize, uint flags);

        [DllImport("setupapi.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static internal extern bool SetupDiEnumDeviceInfo(IntPtr deviceInfoSet, int memberIndex, ref SP_DEVINFO_DATA deviceInfoData);

        [DllImport("setupapi.dll")]
        static internal extern int SetupDiDestroyDeviceInfoList(IntPtr deviceInfoSet);

        [DllImport("setupapi.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static internal extern bool SetupDiEnumDeviceInterfaces(IntPtr deviceInfoSet, ref SP_DEVINFO_DATA deviceInfoData, ref Guid interfaceClassGuid, int memberIndex, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData);

        [DllImport("setupapi.dll", CharSet = CharSet.Auto, BestFitMapping = false)]
        static internal extern IntPtr SetupDiGetClassDevs(ref System.Guid classGuid, string enumerator, IntPtr hwndParent, int flags);

        [DllImport("setupapi.dll", CharSet = CharSet.Auto, EntryPoint = "SetupDiGetDeviceInterfaceDetail")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static internal extern bool SetupDiGetDeviceInterfaceDetailBuffer(IntPtr deviceInfoSet, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData, IntPtr deviceInterfaceDetailData, int deviceInterfaceDetailDataSize, ref int requiredSize, IntPtr deviceInfoData);

        [DllImport("setupapi.dll", CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static internal extern bool SetupDiGetDeviceInterfaceDetail(IntPtr deviceInfoSet, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData, ref SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData, int deviceInterfaceDetailDataSize, ref int requiredSize, IntPtr deviceInfoData);

        internal const short HIDP_INPUT = 0;
        internal const short HIDP_OUTPUT = 1;

        internal const short HIDP_FEATURE = 2;
        [StructLayout(LayoutKind.Sequential)]
        internal struct HIDD_ATTRIBUTES
        {
            internal int Size;
            internal ushort VendorID;
            internal ushort ProductID;
            internal short VersionNumber;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct HIDP_CAPS
        {
            internal short Usage;
            internal short UsagePage;
            internal short InputReportByteLength;
            internal short OutputReportByteLength;
            internal short FeatureReportByteLength;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
            internal short[] Reserved;
            internal short NumberLinkCollectionNodes;
            internal short NumberInputButtonCaps;
            internal short NumberInputValueCaps;
            internal short NumberInputDataIndices;
            internal short NumberOutputButtonCaps;
            internal short NumberOutputValueCaps;
            internal short NumberOutputDataIndices;
            internal short NumberFeatureButtonCaps;
            internal short NumberFeatureValueCaps;
            internal short NumberFeatureDataIndices;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct HIDP_VALUE_CAPS
        {
            internal short UsagePage;
            internal byte ReportID;
            internal int IsAlias;
            internal short BitField;
            internal short LinkCollection;
            internal short LinkUsage;
            internal short LinkUsagePage;
            internal int IsRange;
            internal int IsStringRange;
            internal int IsDesignatorRange;
            internal int IsAbsolute;
            internal int HasNull;
            internal byte Reserved;
            internal short BitSize;
            internal short ReportCount;
            internal short Reserved2;
            internal short Reserved3;
            internal short Reserved4;
            internal short Reserved5;
            internal short Reserved6;
            internal int LogicalMin;
            internal int LogicalMax;
            internal int PhysicalMin;
            internal int PhysicalMax;
            internal short UsageMin;
            internal short UsageMax;
            internal short StringMin;
            internal short StringMax;
            internal short DesignatorMin;
            internal short DesignatorMax;
            internal short DataIndexMin;
            internal short DataIndexMax;
        }

        [DllImport("hid.dll")]
        [return: MarshalAs(UnmanagedType.U1)]
        static internal extern bool HidD_GetAttributes(IntPtr hidDeviceObject, ref HIDD_ATTRIBUTES attributes);

        [DllImport("hid.dll")]
        static internal extern void HidD_GetHidGuid(ref Guid hidGuid);

        [DllImport("hid.dll")]
        [return: MarshalAs(UnmanagedType.U1)]
        static internal extern bool HidD_GetPreparsedData(IntPtr hidDeviceObject, ref IntPtr preparsedData);

        [DllImport("hid.dll")]
        [return: MarshalAs(UnmanagedType.U1)]
        static internal extern bool HidD_FreePreparsedData(IntPtr preparsedData);

        [DllImport("hid.dll")]
        [return: MarshalAs(UnmanagedType.U1)]
        static internal extern bool HidD_SetFeature(IntPtr hidDeviceObject, byte[] lpReportBuffer, int reportBufferLength);

        [DllImport("hid.dll")]
        static internal extern int HidP_GetCaps(IntPtr preparsedData, ref HIDP_CAPS capabilities);
    }
}

HidDevice.Write(byte[] data) always return false

I'm using version 3.0.0.0 of your HidLibrary on Windows 7 x64.

I'm seeing the device events from my USB device and can read from it, but every Write fails.
Does you have any idea what the reason could be?

Regards,
Bart

OnReport

I am writing a program in VB.net
I have converted some of the code over and got most everything working except for the OnReport calls. It does work, but I am losing data. I will only receive part of the packets returned if they are sent too quickly from my device. I can do a polling receive and get all the data returned. I was using mcHID.dll with VB6 and it does not like .net. This one seems very well done but I would like the event driven to work properly. Is there anything I can do? Is there another way to prevent cross threading?

_device.ReadReport(AddressOf OnReport)
...
    Private Sub OnReport(report As HidReport)
        Dim x As Integer
        Dim buff(64) As Byte
        While _device.IsConnected AndAlso report.Data.Length >= 36
            Dim InData As HidDeviceData
            InData = _device.Read
            For x = 0 To 35 Step 1
                buff(x) = InData.Data(x + 1)
            Next
            DataRecieved(buff) 'Needed to stop cross threading
        End While
        _device.ReadReport(AddressOf OnReport)
    End Sub

'*******Needed to stop cross threading *************
   Delegate Sub DataRecievedCallback(UsbIN() As Byte)
    Private Sub DataRecieved(ByVal UsbIN() As Byte)
        Dim x As Integer
        If Me.TextBox_Cell.InvokeRequired Then
            Dim d As New DataRecievedCallback(AddressOf DataRecieved)
            Me.Invoke(d, New Object() {UsbIN})
        Else
            For x = 0 To 35 Step 1
                BufferIn(x) = UsbIN(x)
            Next
            Dlg_OnDataReceived()
        End If
    End Sub

'********* Pooling Recieve *****************
        data(36) = 3
        'Dim report As New HidReport(36, New HidDeviceData(data, HidDeviceData.ReadStatus.Success))
        SuccessTrans = _device.Write(data)
        Console.WriteLine(SuccessTrans & " Grain Info")
        For y = 0 To 50 Step 1
            Dim InData As HidDeviceData
            InData = _device.Read(1000)
            For x = 0 To 35 Step 1
                BufferIn(x) = InData.Data(x + 1)
            Next
            Dlg_OnDataReceived()
        Next

closeDevice() locks up

hi. i have issues calling .CloseDevice() - it locks up my application.

i tried the sample console application and i get the same thing - the application locks up forever after the .CloseDevice() method is called.

thanks.

ReadReport lost data

I have next function for read data:

private bool ReadReport(out List<byte> barray)
        {
            barray = new List<byte>();

            if (_device == null || !_device.IsConnected) {
                return false;
            }

            var task = Task.Run(() => _device.ReadReport());
            if (!task.Wait(TimeSpan.FromMilliseconds(100)))
                return false;

            var inData = task.Result;
            foreach (var b in inData.Data) {
                barray.Add(b);
            }
            return true;
        }

And the part of code that read data from device:

while (true) {
                if (!ReadReport(out binarray))
                {
                    Debug.WriteLine("Read response problem");
                    return;
                }

                response = Encoding.ASCII.GetString(binarray.ToArray()).Split(new char[] { '\n' })[0];

                if (response.StartsWith(EndCommand))
                {
                    break;
                }
                result.Add(response);
                binarray.Clear();
            }

The problem that device returns for me 103 variables, but i only get 32 in result

I'm using version from Nuget

unshared HID?

Does this library have the feature that prevents other process to open the "opened" hid device?

If so, how do I set that up on my application?

reading HID reports

Hi mike,
I do need your library. Thanks for the work.
I'm already able to send send reports and this works fine.
But if I want to read reports from the device, I'm implementing an CM119A from C-Media, then the problem starts.
Sometimes the program is running through and I get the input report; and sometimes not.
I'm using ReadReport and WriteReport. As I need async-read (ReadReport) I wouldn't expect an error.
Some code:

HidDeviceList = HidDevices.Enumerate(0x0D8C, 0x000E);

            report_get = new HidReport(4);
            if (HidDeviceList.Count<HidDevice>() > 0)
            {
                // Grab the first device
                HidDevice = HidDeviceList.First<HidDevice>();
                OutData[0] = 0x00;
                OutData[1] = 0x00;
                OutData[2] = 0x00;
                OutData[3] = 0x40;
                report_post.Data = OutData;
                HidDevice.WriteReport(report_post);
                report_get = HidDevice.ReadReport(); // here the program hangs
                ...

Do you have any idea?

Getting input from hid device..

how will i detect when a key is pressed on the hid device.. i want to make an app to assign a task to a button that is pressed on the hid device. so which method will i use for that?

High CPU consuming reading data

Hello!

First of all, thanks for this excellent library. Its really powerful.

Im comunicating my software(written in VB .NET 2010) on Windows 7 x86 with a custom HID device made by me. Target endpoint size is 32 bytes and period is 32(ms).

Im calling Listen() just once after executing the OpenDevice(). Then this code make the continuous data reading:

Private Sub Listen()
    HidPIC18.ReadReport(New HidDevice.ReadReportCallback(AddressOf OnDataReceived))
End Sub

Private Sub OnDataReceived(ByVal hr As HidReport)
    Listen()
End Sub

It works, but i've just discovered that CPU consuming is very high. Am i doing something wrong? I'm using the correct method to read data in asynchronous mode? Is there a better way to read async data from Device?

Thanks!

The IsConnected method is notworking with VB.NET (JerryMouse)

It really sounds irrational but I called the APIs from VB 2008 just like C#. I found the device using the Enumerate method, however, the device is reported as disconnected !!!

I tested the same code using C# and the device was connected !!!. I would never post such a thing unless I'm 100 % certain that there is something wrong that I hope you can help me to figure out.

I'll enclose the VB Project with is very trivial so that you can see yourself. Again the very same C# code works fine.

Sometimes library lost data from device.

Hello.

I have some problems with library, when my device return answer from commands, sometimes library receive zeros byte array, but in sniffer I get valid information. Can you explain this behavior?

For example: device send data : 04(id) 01 00 00 00 ... ect.
Sometimes ReadReport resive: 00 00 00 00 .. ect. I understand that ReadReport delete id package, but when i debug this method - i see that sometimes library recive all zero's including id package.

For receive information I use ReadReport with callback. For send information I used WriteReportAsync.

Best regards, Alexander.

Cannot Add Reference to Project

When I try to add the library to my references the path shows and version 0.0.0.0

I am trying to use HidLibrary 3.0.0, Im using VS 2008 , XP x86, Visual Basic

I have HidLibrary 2.0.1 and can add that fine

HIDReport constructor creating report size incorrectly + fix

The HIDReport class has an issue with one of its constructors.

    public HidReport(int reportSize)
    {
        Array.Resize(ref _data, reportSize);
    }

vs.

    public HidReport(int reportSize, HidDeviceData deviceData)
    {
        _status = deviceData.Status;

        Array.Resize(ref _data, reportSize - 1);

The difference is the reportSize - 1 in the second constructor is correct, while the reportSize alone in the first constructor is not. The end result is when a report is written later on, the output buffer becomes size 66 instead of 65(GetBytes copies the data array to an output data array of sizeof(data array )+ 1) and ALL the bytes in the data are effectively offset by 1 in index. This only affects HidReport if initialized with the first constructor(which HIDDevice does when you call Create Report)

I encountered this when trying to figure out why I was getting the command data byte on my microcontroller in its internal data array at index 1 instead of the expected index 0 which other HID libraries did not cause.

This may be related to the issue where people say WriteFile returns false, because it would be passing a 66 byte array or whatever size they may have + 1 instead of the proper result if they used CreateReport.

System.MissingMethodException thrown from HidDevices.Enumerate

Hi Mike and friends,

I recently upgraded my Nuget package from 3.2.23 to 3.2.29 and am receiving a MissingMethodException when enumerating my device,

Exception content

System.MissingMethodException was unhandled
  HResult=-2146233069
  Message=Method not found: 'Int32 System.Runtime.InteropServices.Marshal.SizeOf(!!0)'.
  Source=HidLibrary
  StackTrace:
       at HidLibrary.HidDevices.EnumerateDevices()
       at HidLibrary.HidDevices.Enumerate(Int32 vendorId, Int32[] productIds) in d:\TeamCity\BuildAgent\work\26c2362cad24d4c8\src\HidLibrary\HidDevices.cs:line 35
       at HIDDeviceTest.Program.Main(String[] args) in x:\GitFlow\XP01\HIDDeviceTest\HIDDeviceTest\Program.cs:line 22
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:

Environment

  • The exception happens with all overloads and is not present in version 3.2.28.
  • I have .NET Framework 4.5 installed but no higher that I can see.
  • Operating System: Windows 7 x64

I imagine the .NET version is the problem but I wanted to let you know. I'm fairly sure Nuget shouldn't have let me add it to me project!

Magellan 1100i barcode reader

I downloaded your Hid Library project and in the examples folder I saw that there is a sample for Magtek card reader, currently I'm working on a similar product called Magellan 1100i barcode reader. So what I did was to copy the code from magtek card reader sample and changed the GetCardData method, but I'm not able to make it work, could you please help.

Magtek card reader sample

if (data != null && data.Length == 337)
 {
     if (data[0] == 1 || data[1] == 1 || data[2] == 1)
     {
         Error = true;
         _errorMessage = "Error reading data";
         return null;
     }
     var cardData = new byte[data[3] + data[4] + data[5]];
     Array.Copy(data, 7, cardData, 0, data[3]);
     Array.Copy(data, 117, cardData, data[3], data[4]);
     Array.Copy(data, 227, cardData, data[3] + data[4], data[5]);
     return cardData;
 }

Datalogic Magellan 1100i

ProductId: 0x2602
VendorId: 0x05F9
The changed code, since the magellan 1100i has the data length of 8

if (data != null && data.Length == 8)
{
    if (data[0] == 1 || data[1] == 1 || data[2] == 1)
    {
        Error = true;
        _errorMessage = "Error reading data";
        return null;
    }
    var cardData = new byte[data[2] + data[3] + data[4]];
    Array.Copy(data, 1, cardData, 1, data[3]);
    Array.Copy(data, 2, cardData, data[2], data[3]);
    Array.Copy(data, 3, cardData, data[3] + data[4], data[5]);
    return cardData;
}

Thanks
Jay

ReadProduct fails to return data

The underlying code in NativeMethod.cs HidD_GetProductString needs a larger buffer.
It is set at 64 bytes. MS API states 126 wide (see below). A wide character is a 2-byte multilingual character code. I changed the ReadProcduct byte array to 252 and it worked for me.

https://msdn.microsoft.com/en-us/library/ff539681.aspx

The maximum possible number of characters in an embedded string is device specific. For USB devices, the maximum string length is 126 wide characters (not including the terminating NULL character).

If the buffer is not large enough to return the entire NULL-terminated embedded string, the routine returns nothing in the buffer.

Missing "else" statement in WriteData function

the try-catch block starting at line 347 of HidDevice.cs should be enclosed inside an else block of the if (_deviceWriteMode == DeviceMode.Overlapped) construct at line 312. otherwise both WriteFile functions are executed regardless of the overlapped mode.

hidlibrary crashes occasionally in ReadReport

Hi,

i'm currently doing some test with hidlibrary.
Occasionaly my test-programm, which literally does nothing than enumarate the devices and uses WriteFeaturedata with exactly one device, crashes with the following exception:
( ReadReport(callback) is running in an endless loop , Overlapped reading is on)

screenshot003

Sometimes this even happens when i do not use WriteFeatureData

Having issue with CloseDevice()

I'm testing this framework out with my own custom USB device and the NativeMethods.CloseHandle() hangs when I call CloseDevice() on the HIDDevices class.

hiddevice.readreport() on Windows 7 x64

When using the hiddevice.readreport() function on Windows 7 machines Im always getting a report with null data in it even though the report.readstatus = HidDeviceData.ReadStatus.Success. Im only seeing this on x64 machines, 32 bit machines work fine.

HID Report Length

Hi

I'm noticed that when I use the HIDLibrary, the Output and Input report length i.e. Capabilities.InputReportByteLength, returns one extra byte. Anyone else notice this ? Is this by design or a bug ?

Thanks, Dave

Is this is a multithreaded library???

HI,
I am planning to use this library to communicate(open,read,write,close) with two or more devices at the same time.Is this possible under windows?

Multiple same type devices, device path included in OnReport?

I am using this excellent library for the Saitek DCS Flightpanels project.
How can I differentiate HID input reports from same type devices?
I tried to see if it was possible to inject the unique Windows Device Path into the callback call for OnReport but my knowledge on WinAPI is close to zero and Google, Pinvoke didn't find enough info for me to work on. As OnReport callback must be Static and no uniqueness are included in the final callback call I don't know which device sent it.
Am I missing something? Thanks for this library, it is a gem.

WriteReportAsync - await Task

Hi!

I'm beginner, so maybe I alone to getting this issue :)

Problem is, when I want to send something with WriteReportAsync (or also WriteReport), report Is NOT send immediately, but is registered when I push button on my device. With any other USB sending program (like "SimpleHIDwrite") works normally. Only now with this C# library I get this issue, always when I want to send something to device, I must press button on my device.

My code stops here (HidDevice.cs):
return await Task.Factory.FromAsync(writeReportDelegate.BeginInvoke, writeReportDelegate.EndInvoke, report, timeout, null);

.. waiting for button on my device to be pressed.

Please for any help!

Issue with ReadReport method with new lib version

Hi, I always used this hid library in my .NET projects (4.0 and above) ver. I wanted to upgrade my lib version, I use the HidLibrary-3.2.28.0, to the newest HidLibrary-3.2.32.0 published few days ago, but I've noticed that my projects doesn't work anymore. Simply updating library and rebuilding solution, when the Write method is called, the sw hangs on this method and the OnReport callback is not being called. I tried to replace library with my old version and all come back to works. I tried even the version 3.2.29.0 but it reproduce the same issue.
My code is implemented as suggested in MagTek CardReader using ReadReport and OnReport Callback.

Can someone help me to understand why my code doesn't work anymore with new version?
Thanks to all.

ReadReport() memory leak

Great library Mike, thanks a lot for this huge work.

The problem is when I want to fill InputReport with data:

InputReport = device.ReadReport();

where InputReport is:

HidLibrary.HidReport InputReport = new HidLibrary.HidReport(device.Capabilities.InputReportByteLength);

It's a very large of leak memory, specially when I read reports in async mode from device (for eg. 100 times for a second). In few minutes it can takes hundreds of megabytes.

I'm beginner in c# programming and didn't find solution for problem desrcibed above ;(

greetings!

Performance problem

Hi,

I'm having a bit of a problem with the performance. I am receiving a lot of data and when I do that my cpu is at 100%.

I ran the Visual Studio performance profiler and it says that 90% of the load come from here:

public HidDeviceData Read(int timeout) if (IsConnected) <------------

And then 80% from here:

        NativeMethods.SetupDiGetDeviceRegistryProperty(deviceInfoSet,
                                                        ref devinfoData,
                                                        NativeMethods.SPDRP_DEVICEDESC,
                                                        ref type,
                                                        descriptionBuffer,
                                                        descriptionBuffer.Length,
                                                        ref requiredSize);

It seems like it is doing a lot of stuff while trying to find out if the device is still connected? Is it necessary to do all of that before every read?

Or did I missunderstand something?

Set Report request issue

Hi HidLibrary Team,

First, thank you for thisHidLibrary, you have made a nice job.

I'm currently trying to drive a RFID reader with you library and I'm wondering how to send an "Set Report" request.
Actually, the method WriteData used the NativeMethod "WriteFile" which make an "ouput" request but how send the "Set Report" request which use the NativeMethod "HidD_SetOutputReport".

thx in advance for your help,

cedric

CardInserted event

Is there any way to get an event when de card is removed from the card reader?
What I am looking for is to create a 'CardStatusChanged' event with 'Inserted' and 'Removed' statusses.

I have been looking through the code. The events 'Connected' and 'Removed' seem to apply to the reader itself.

thx

read, readreport hang up if not resceiving data

Both read and readreport have an overlay with an timeout.
As I understand this, they should release an return nothing ? if this timeouttime is reached.
But they dont, they are still hanging up.
t.ex. Hiddev.readreport(500).

Maybe this timeout means something else??

Kajj

HidLibrary Source Missing?

I really like this library but it's missing some features I need, so I want to see if I can extend it.

I am trying to build it from source, but the source seems to be missing for the HidLibrary namespace. I can build IO.Usb.Hid but the only reference to HidLibrary is in the archive folder.

Maybe I am overlooking something obvious?

Best Regards,
Matt

Magnetic card swipe Windows 10

A strange behavior for the MagtekCardReader example can be reproduced on Windows 10.
If the reader is connected before Windows is started, the device is found, is successfully opened, all events (Attached, Removed, OnReport) are firing, but, when a card is swiped, in "OnReport" the IsConnected property is always false and no data is available in the report (Update: in some cases OnReport is not even firing). Removing and attaching the reader helps - all subsequent swipes are fine and the report data can be read.
I can reproduce it on 2 machines in the office and some clients with Windows 10 also reported this behavior.
Funny thing, if I restart the computer, everything works as expected. The problem appears only when the computer is shut down and then started.

I'm using the latest release (3.2.31)
Did anyone have same problems?
Thanks!

@mikeobrien, thank you for the library, especially for the MagtekCardReader example!

HidDevices.EnumerateHidDevices memory leak due to yield

Running on both XP (32bit) and Windows 7 (64bit) with the Logitech G13 controller - I've noticed severe memory leaking and it appears to be caused by using the yield keyword at line 69, preventing NativeMethods.SetupDiDestroyDeviceInfoList(deviceInfoSet) at line 72 from ever being reached. This can be fixed by removing the yield statement, moving var devices = new List() at line 51 to before the if statement, and returning devices.

Thanks for the great work!

No data on Windows 10 Anniversary without Focus

After I updated my machines which were using your Library to Acces a XBox One Controller without any problem (thanks a lot to that software) to Windows 10 Anniversary edition, I observed achange in the behaviour of HID devices. It is pretty clear that Microsoft changed something in their API, but maybe someone already firgured out how to avoid this.
Several Forums filled with threads after Windows 10 Anniversary Update was released. Microsoft changed the way HID Devices were accessed. Obviously, Windows opened all devices by itself, preventing any other program to open the device in exclusive mode (becaus it was opened already).

See:

Also Steam had some problems with XBox controllers (https://steamcommunity.com/app/367500/discussions/0/353916584661137682/). Apparently, there was a fix by Mirosoft (KB3176938). This prevents Windows from opening all Devices.

But another thing changed in that update. Before, i used this library as-is. This means the HID will be opened in Shared Access mode by calling CreateFile (https://github.com/mikeobrien/HidLibrary/blob/master/src/HidLibrary/NativeMethods.cs#L55) with Parameters Read/Write Mode = Overlapped and ShareMode = ShareRead | ShareWrite. Now, my Application only will receive Data when it has Focus. When Focusing any other Window or the Desktop, there will by no events (Reports) fired. After Re-Focusing the Window, everything works as before. The Issue is clearly not caused by this library since Evenghost (which is written in Python, http://www.eventghost.org/) now shows the same behaviour.
Now, i tried to open the Device in Exclusive Mode, changing the shareMode to ShareMode.Exclusive and Read/Write mode to Non-Overlapped (which should be possible since I installen the fix above). This seems not to be sucessfull. The CreateFile-Methode returns a valid handle, but the Report-Method is constantly Fired. The Data attached to the Report has the correct length but is completely zero. To be more precise, the data is noch changed after initialization. If i write dummy data into the buffer, the data remains unchanged after calling ReadFile.

Has anyone suceeded in opening a device in exclusive mode using this library?

Swipe Event?

I've been trying to figure out how to check if a card has been swiped. Is there any documentation on how to check for a card being swiped? Right now when I swipe a card it just fills a text box in my C# program but it doesn't even need the HID library for that. I'd like to know if I can check for a Swipe Event so i can process the data from the card into the correct text boxes.

Timeout in ReadReport method does not work

mikeobrien / HidLibrary / src / HidLibrary / HidDevice.cs

In order to read the port, I using the ReadReport method. But when a command did not came and no data is available, this method became unresponsive. When I trying to set a timeout into an overloaded version of this method (ReadReport(1000), for example), this does not work and became unresponsive too. So, the timeout in your library does not work.
The same things is related to the ReadReportAsync method and, likely, to the writing methods as well.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.