1

I am trying to implement this solution by Hans Passant here for HID plug and play scanner: How to receive Plug & Play device notifications without a windows form

It works great and gives me top level win messages for DBT_DEVNODES_CHANGED 0x0007 "A device has been added to or removed from the system." However I need to register for notifications to get DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE messages. So I added a method for it but I am getting an error during call to NativeMethods.RegisterDeviceNotification "MInstance.Handle threw System.InvalidOperationException" Here is my code, includes my RegisterNotifications() method and slightly modded original code from above URL.

    public static DeviceNotificationControl MInstance { get; private set; }

    public static void Start(string devicePathName)
    {
        Thread t = new Thread(() => runForm(devicePathName)); 
        t.SetApartmentState(ApartmentState.STA);
        t.IsBackground = true;
        t.Start();
    }

    public static void Stop()
    {
        if (MInstance == null) throw new InvalidOperationException("Notifier not started");
        DeviceNotify = null;
        MInstance.Invoke(new MethodInvoker(MInstance.endForm));
    }

    public static DeviceNotificationControl GetInstance()
    {
        if (MInstance != null)
            return MInstance;
        return null;
    }

    [STAThread]
    private static void runForm(string devicePathName)
    {
        Application.Run(new DeviceNotificationControl(devicePathName));
    }

    protected override void SetVisibleCore(bool value)
    {
        // Prevent window visibility
        if (MInstance == null)
        {
            CreateHandle();
            if (this.IsHandleCreated)
                MInstance = this;
        }
        value = false;
        base.SetVisibleCore(value);
    }

    private void endForm()
    {
        this.Close();
    }

    public static bool RegisterNotifications()
    {
        if (_notificationHandle != IntPtr.Zero)
            throw new InvalidOperationException("Already registered for notifications.");

        if (MInstance == null)
            throw new InvalidOperationException("The notification control has not been created.");

        var hidGuid = new Guid("4d1e55b2-f16f-11cf-88cb-001111000030");

        NativeMethods.DEV_BROADCAST_DEVICEINTERFACE devBroadcast = new NativeMethods.DEV_BROADCAST_DEVICEINTERFACE();
        IntPtr devBroadcastBuffer = IntPtr.Zero;

        int size = Marshal.SizeOf(devBroadcast);
        devBroadcast.dbcc_reserved = 0;
        devBroadcast.dbcc_size = size;
        devBroadcast.dbcc_devicetype = NativeMethods.DBT_DEVTYP_DEVICEINTERFACE;
        devBroadcast.dbcc_classguid = hidGuid;

        try
        {
            devBroadcastBuffer = Marshal.AllocHGlobal(size);
            Marshal.StructureToPtr(devBroadcast, devBroadcastBuffer, true);
            _notificationHandle = NativeMethods.RegisterDeviceNotification(MInstance.Handle, devBroadcastBuffer, NativeMethods.DEVICE_NOTIFY_WINDOW_HANDLE);
            Marshal.PtrToStructure(devBroadcastBuffer, devBroadcast);

            if (_notificationHandle == IntPtr.Zero)
                return false;

            return true;
        }
        finally
        {
            if (devBroadcastBuffer != IntPtr.Zero)
                Marshal.FreeHGlobal(devBroadcastBuffer);
        }
    }

Any suggestions/ideas are greatly appreciated!

0 Answers0