5

I am developing a C# .NET 2.0 application wherein I need to scan for an attached HID. How can this be done? Because it is a HID, Windows does not assign a COM port to it. I only need to programmatically determine if the device is attached. Thank you.

ADDITIONAL INFORMATION

When I connect the USB device to my computer two entries appear under Human Interface Devices in the Device Manager. Clicking into their Properties yields this information in their respective Details tabs:

HID-compliant device Device Instance Id: HID\VID_1795&PID_6004\7&2694D932&0&0000

USB Human Interface Device Device Instance Id: USB\VID_1795&PID_6004\B973000000EB0D00

Jørgen R
  • 9,179
  • 7
  • 36
  • 56
Jim Fell
  • 12,390
  • 29
  • 117
  • 192

2 Answers2

6

In the WMI Code Creator select these options:

Namespace: root\WMI

Class: MSWmi_PnPInstanceNames

Select InstanceNames from the Results box for the following code:

using System;
using System.Management;
using System.Windows.Forms;

namespace WMISample
{
    public class MyWMIQuery
    {
        public static void Main()
        {
            try
            {
                ManagementObjectSearcher searcher = 
                    new ManagementObjectSearcher("root\\WMI", 
                    "SELECT * FROM MSWmi_PnPInstanceNames"); 

                foreach (ManagementObject queryObj in searcher.Get())
                {
                    Console.WriteLine("-----------------------------------");
                    Console.WriteLine("MSWmi_PnPInstanceNames instance");
                    Console.WriteLine("-----------------------------------");
                    Console.WriteLine("InstanceName: {0}", queryObj["InstanceName"]);
                }
            }
            catch (ManagementException e)
            {
                MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
            }
        }
    }
}
Jim Fell
  • 12,390
  • 29
  • 117
  • 192
  • 1
    An error occurred while querying for WMI data: Access denied – themhz Oct 19 '20 at 01:07
  • It's been a long time since I've needed to use WMI, but a quick internet search yields some helpful results. Maybe this will help: https://docs.microsoft.com/en-us/windows/win32/wmisdk/user-account-control-and-wmi#account-needed-to-run-wmi-command-line-tools – Jim Fell Oct 19 '20 at 14:16
  • Thanx for the help. I finally figured out to run the visual studio as administrator and I can get my wmi list. I wonder how this can help me listen to my RFID events. My device is connected to the usb port and windows is showing the device in Human Interface Devices(HID). This laptp has no ports so many exampes that are using COM names dont work. No COM on this commputer. However I am hoping if i can access my RFID device from WMI giving some kind of query.. not sure though. – themhz Oct 20 '20 at 16:51
0

Here is an example of enumerating Hid devices on Windows:

    public static ConnectedDeviceDefinition GetDeviceDefinition(string deviceId, SafeFileHandle safeFileHandle)
    {
        try
        {
            var hidAttributes = GetHidAttributes(safeFileHandle);
            var hidCollectionCapabilities = GetHidCapabilities(safeFileHandle);
            var manufacturer = GetManufacturer(safeFileHandle);
            var serialNumber = GetSerialNumber(safeFileHandle);
            var product = GetProduct(safeFileHandle);

            return new ConnectedDeviceDefinition(deviceId)
            {
                WriteBufferSize = hidCollectionCapabilities.OutputReportByteLength,
                ReadBufferSize = hidCollectionCapabilities.InputReportByteLength,
                Manufacturer = manufacturer,
                ProductName = product,
                ProductId = (ushort)hidAttributes.ProductId,
                SerialNumber = serialNumber,
                Usage = hidCollectionCapabilities.Usage,
                UsagePage = hidCollectionCapabilities.UsagePage,
                VendorId = (ushort)hidAttributes.VendorId,
                VersionNumber = (ushort)hidAttributes.VersionNumber,
                DeviceType = DeviceType.Hid
            };
        }
        catch (Exception)
        {
            return null;
        }
    }

Full class here: https://github.com/MelbourneDeveloper/Device.Net/blob/master/src/Hid.Net/Windows/WindowsHidDeviceFactory.cs

API Calls here: https://github.com/MelbourneDeveloper/Device.Net/blob/master/src/Hid.Net/Windows/HidAPICalls.cs

Here is a similar thing for Windows 10 (UWP):

    public async Task<IEnumerable<ConnectedDeviceDefinition>> GetConnectedDeviceDefinitions(FilterDeviceDefinition deviceDefinition)
    {
        var aqsFilter = GetAqsFilter(deviceDefinition.VendorId, deviceDefinition.ProductId);

        var deviceInformationCollection = await wde.DeviceInformation.FindAllAsync(aqsFilter).AsTask();

        var deviceDefinitions = deviceInformationCollection.Select(d => GetDeviceInformation(d, DeviceType));

        var deviceDefinitionList = new List<ConnectedDeviceDefinition>();

        foreach (var deviceDef in deviceDefinitions)
        {
            var connectionInformation = await TestConnection(deviceDef.DeviceId);
            if (connectionInformation.CanConnect)
            {
                await Task.Delay(1000);

                deviceDef.UsagePage = connectionInformation.UsagePage;

                deviceDefinitionList.Add(deviceDef);
            }
        }

        return deviceDefinitionList;
    }

Code:https://github.com/MelbourneDeveloper/Device.Net/blob/77439b1ab0f4b3ad97376e4e62c7efac0a749783/src/Device.Net.UWP/UWPDeviceFactoryBase.cs#L47

Android (https://github.com/MelbourneDeveloper/Device.Net/blob/77439b1ab0f4b3ad97376e4e62c7efac0a749783/src/Usb.Net.Android/AndroidUsbDeviceFactory.cs#L31):

    public Task<IEnumerable<ConnectedDeviceDefinition>> GetConnectedDeviceDefinitions(FilterDeviceDefinition deviceDefinition)
    {
        return Task.Run<IEnumerable<ConnectedDeviceDefinition>>(() =>
        {
            //TODO: Get more details about the device.
            return UsbManager.DeviceList.Select(kvp => kvp.Value).Where(d => deviceDefinition.VendorId == d.VendorId && deviceDefinition.ProductId == d.ProductId).Select(GetAndroidDeviceDefinition).ToList();
        });
    }

Using Hid.Net, you can enumerate devices in the same way on any platform like below. See the full article.

var devices = await DeviceManager.Current.GetConnectedDeviceDefinitions(new FilterDeviceDefinition { VendorId = 0x1209, ProductId = 0x53C1 });
foreach (var device in devices)
{
    Debug.WriteLine(device.DeviceId);
}
Christian Findlay
  • 4,791
  • 1
  • 33
  • 74
  • All the links are broken here – HaBo Jan 18 '19 at 06:55
  • @HaBo I have updated the answer and corrected the links. – Christian Findlay Jan 18 '19 at 08:26
  • Hi Since your links were not working I looked at other option and found HidSharp and am able to get to a point but stuck with chip selection https://stackoverflow.com/questions/54250503/write-to-hid-with-chip-selection-with-net-console-app would you be able help me with this question. I am fine with Hid.NET or HIDSharp – HaBo Jan 18 '19 at 08:58
  • @HaBo have a look at this wiki https://github.com/MelbourneDeveloper/Device.Net/wiki/Enumerating-Connected-Devices. You can enumerate through devices with it. Then, you can read/write here: https://github.com/MelbourneDeveloper/Device.Net/wiki/Writing-To-and-Reading-From-a-Device. If you reword your question slightly, I will post code on how to solve the problem with Hid.Net, but your question is HidSharp specific. – Christian Findlay Jan 18 '19 at 09:06
  • I installed Hid.NET 2.3.0 from nuget. And tried to run this Go function https://github.com/MelbourneDeveloper/Device.Net/blob/c91415192e516f4fd5e092dfdb76cc467169a300/src/Usb.Net.WindowsSample/Program.cs#L38 it doesn't recognize DeviceDefinition type – HaBo Jan 18 '19 at 09:13
  • Did you change the VendorId, and ProductId values? Also, di you try scanning through all devices? var devices = await DeviceManager.Current.GetConnectedDeviceDefinitions(null, null); – Christian Findlay Jan 18 '19 at 09:20
  • Did you register the Hid Device Factory? @HaBo – Christian Findlay Jan 18 '19 at 09:20
  • its compile time error. I am not able to compile the code as it is missing type DeviceDefinition – HaBo Jan 18 '19 at 09:24
  • Ah. Thanks for pointing that out. The code has changed. This is the updated example. It's much simpler. https://github.com/MelbourneDeveloper/Device.Net/blob/master/src/Usb.Net.WindowsSample/Program.cs – Christian Findlay Jan 18 '19 at 09:28
  • @HaBo I have completely replaces the code examples in this article with the latest code: https://github.com/MelbourneDeveloper/Device.Net/wiki/Enumerating-Connected-Devices. Thanks so much for pointing out the mistakes. – Christian Findlay Jan 18 '19 at 09:35
  • 1
    Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/186915/discussion-between-habo-and-melbourne-developer). – HaBo Jan 18 '19 at 09:49
  • Also where is the chip selection option in the code? – HaBo Jan 18 '19 at 09:50
  • Yep. All of the information you need looks like it's on page 11 of the data sheet but it's definitely specific to the device so it's not something I have any knowledge of. – Christian Findlay Jan 18 '19 at 20:19
  • It's on the to-do list. https://github.com/MelbourneDeveloper/Device.Net/issues/27 – Christian Findlay Jan 22 '19 at 08:08
  • Can you please share the code you have or COM port read and write, As I am developing app that talks to HIDs on a parallel thread I need to talk to COM ports as well so I felt it will be nice if both my HID and COM providers are derived from same library ans signatures. If your code is giving what I need, than I can spend some time to integrate with Device.NET – HaBo Jan 22 '19 at 08:17
  • This code works pretty well. https://stackoverflow.com/a/9092519/1878141. I've used it for reading from GPS devices. But, please see the issue on Github: https://github.com/MelbourneDeveloper/Device.Net/issues/27 – Christian Findlay Jan 22 '19 at 09:19