Jinjinov / Usb.Events

Subscribe to the Inserted and Removed events to be notified when a USB drive is plugged in or unplugged, or when a USB device is connected or disconnected. Usb.Events is a .NET Standard 2.0 library and uses WMI on Windows, libudev on Linux and IOKit on macOS.
MIT License
95 stars 23 forks source link

Triggering events works only two times under windows #27

Closed AnnikaJoo closed 1 year ago

AnnikaJoo commented 1 year ago

Library version

10.1.0.1

OS & OS version

Windows 10

Describe the bug

Hello all,

I am using your Nuget Package in my application to determine if specific USB-devices are added or removed. On Windows I have the problem that this functionality works only two times and after that the event is not triggered anymore. Is this a known issue or what could be responsible for this?

To Reproduce

public void WatchUsbActions()
    {
        _usbEventWatcher.UsbDeviceRemoved += (_, device) =>
        {
            // Detect, if we know the device
            var type = ReaderType.IdentifyReader(device.DeviceName);

            // locking variable, set to true, after application is fully initialized
            if (_usbEventProcessingEnabled)
            {
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    // locking variable to prevent multiple events after device removal
                    if (!_notifiedLock)
                    {
                        _notifiedLock = true;

                        Task.Delay(UsbEventDelay).ContinueWith(t => OnReaderChanged?.Invoke(this, false));
                        Task.Delay(500).ContinueWith(t => _notifiedLock = false); //renable event broadcast
                    }
                }
                else
                {
                    if (type == ReaderType.Unknown)
                    {
                        return;
                    }

                    Task.Delay(UsbEventDelay).ContinueWith(t => OnReaderChanged?.Invoke(this, false));
                }
            }
        };
        _usbEventWatcher.UsbDeviceAdded += (_, device) =>
        {
            // Identify device
            var type = ReaderType.IdentifyReader(device.DeviceName);
            if (type == ReaderType.Unknown)
            {
                return;
            }

            if (_usbEventProcessingEnabled)
            {
                Task.Delay(UsbEventDelay).ContinueWith(t => OnReaderChanged?.Invoke(this, true));
            }
        };

Expected behavior

I expect the events UsbDeviceRemoved and UsbDeviceAdded to be triggered on every usb change

Jinjinov commented 1 year ago

Thank you for noticing this. This is not a known issue.

I tried it with a few devices right now, it works ok for most of them - I can add and remove them many times and it always works.

But I found one device that triggers the added event only one time. I will investigate.

Jinjinov commented 1 year ago

I have found out that this sometimes stops working for unknown reason for some devices:

"SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBControllerDevice'"

This always works for all devices, but it is CPU intensive:

"SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_PnPEntity'"

I will make a new NuGet version and will provide this as an option.

The default option will be Win32_USBControllerDevice which works for most devices - and you will be able to choose Win32_PnPEntity which works for all devices, but is more CPU intensive.

Jinjinov commented 1 year ago

Fixed in https://github.com/Jinjinov/Usb.Events/releases/tag/v10.1.1.0

AnnikaJoo commented 1 year ago

Thanks for your quick fix. With the option it works now :)