The main issue is that the WM_DEVICECHANGE only comes for information you registered, with a few exceptions as can be read in the remarks of RegisterDeviceNotification.
Here are the details what you need to do:
To get the WM_DEVICECHANGE with DBT_DEVICEARRIVAL for devices, you need to call the Win32 API in user32.dll called RegisterDeviceNotification with a correctly filled DEV_BROADCAST_DEVICEINTERFACE_W struct.
If done so correctly you will get WM_DEVICECHANGE messages, which contain the event type (in our case DBT_DEVICEARRIVAL) as described in the Device Management Events, and a pointer to details. The pointer needs to be read as the DEV_BROADCAST_HDR struct , allowing you to recognise if this is indeed the DEV_BROADCAST_DEVICEINTERFACE_W struct. If so this struct will contain a name, which you will need to parse at it contains the VID & PID.
That is quite a lot to process, and it took me a couple of hours to get it right. If you need a quick solution, and skip implementing the horrible details, add the NuGet package Dapplo.Windows.Messages (VID & PID are available with 0.9.7 and later) to your project. Use the following code only once, otherwise your code will be called multiple times, there is no need to do this from a Window but it must be from a Windows Forms or WPF application:
var deviceNotificationSubscription = DeviceNotification
.OnDeviceArrival()
.Subscribe(deviceInterfaceChangeInfo => {
// Your code goes here, and will be automatically called
var vid = deviceInterfaceChangeInfo.Device.VendorId;
var pid = deviceInterfaceChangeInfo.Device.ProductId;
});
My library highly depend on System.Reactive, I won't go into details here, which allows a more functional approach to your application. You can stop receiving the events by calling deviceNotificationSubscription.Dispose();
The library creates it's own hidden message window to receive the window messages, so you can even continue receiving the information in the background.
The Device property of the DeviceInterfaceChangeInfo has the DevBroadcastDeviceInterface struct, which contains the original Win32 information, but additionally has some higher level properties like:
- a friendly name, which is retrieved from the registry
- device type like USB, HID etc including an IsUSB
- vendor ID
- product ID
- a DeviceInterfaceClass enum for easier code access to the class
- a generated URL to get more information on the device
Let me know if this works and helps here by and if you have any questions raise an issue on my Dapplo.Windows GitHub project! There is a lot more in this library but unfortunately most documentation still needs writing.