Search code examples
.netvb.netdllusbwinusb

How can I use RegisterDeviceNotification without a window handle?


I'm writing a DLL library that interfaces to a USB device using winusb in VB.NET.

Since it's a DLL, I have no window, and it's possible that users of my library will also not have a window (command line apps, for instance).

The examples I've seen that detect device attach and detach all use RegisterDeviceNotification which requires a window handle to receive the attach/detach messages at.

How do I receive these messages directly into a function without a window to get a handle from?


Solution

  • I recently found a solution that seems more elegant than RegisterDeviceNotification for an application without a GUI.

        void onEventArrived(object sender, EventArrivedEventArgs e)
        {
            ManagementBaseObject _o = e.NewEvent["TargetInstance"] as ManagementBaseObject;
    
            if (_o != null)
            {
                using (ManagementObject mo = new ManagementObject(_o["Dependent"].ToString()))
                {
                    if (mo != null)
                    {
                        try
                        {
                            if (mo.GetPropertyValue("DeviceID").ToString() != string.Empty)
                            {
                                //connected
                            }
                        }
    
                        catch (ManagementException ex)
                        {
                            //disconnected
                        }
                    }
                }
            }
        }
    

    Initialize this code by calling

            System.Management.WqlEventQuery _q = new WqlEventQuery("__InstanceOperationEvent", "TargetInstance ISA 'Win32_USBControllerDevice' ");
            _q.WithinInterval = TimeSpan.FromSeconds(1);
            ManagementEventWatcher _w = new ManagementEventWatcher(_q);
            _w.EventArrived += new EventArrivedEventHandler(onEventArrived);
            _w.Start();
    

    Also make sure to add a reference to System.Management