zoukankan      html  css  js  c++  java
  • C# USB Detection winform and WPF

    Win From Version:

    代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Management;
    using System.Runtime.InteropServices;


    namespace SyncContactDemo
    {
        
    class DriverWindow : NativeWindow, IDisposable
        {
            
    // Contains information about a logical volume.

            [StructLayout(LayoutKind.Sequential)]
            
    public struct DEV_BROADCAST_VOLUME
            {
                
    public int dbcv_size;            // size of the struct
                public int dbcv_devicetype;        // DBT_DEVTYP_VOLUME
                public int dbcv_reserved;        // reserved; do not use
                public int dbcv_unitmask;        // Bit 0=A, bit 1=B, and so on (bitmask)
                public short dbcv_flags;        // DBTF_MEDIA=0x01, DBTF_NET=0x02 (bitmask)
            }


            
    private const int WM_DEVICECHANGE = 0x0219;                // device state change
            private const int DBT_DEVICEARRIVAL = 0x8000;            // detected a new device
            private const int DBT_DEVICEQUERYREMOVE = 0x8001;        // preparing to remove
            private const int DBT_DEVICEREMOVECOMPLETE = 0x8004;    // removed 
            private const int DBT_DEVTYP_VOLUME = 0x00000002;        // logical volume


            
    public DriverWindow()
            {
                
    // create a generic window with no class name
                base.CreateHandle(new CreateParams());
            }


            
    public void Dispose()
            {
                
    base.DestroyHandle();
                GC.SuppressFinalize(
    this);
            }

            
    protected override void WndProc(ref Message message)
            {
                
    base.WndProc(ref message);

                
    if ((message.Msg == WM_DEVICECHANGE) && (message.LParam != IntPtr.Zero))
                {
                    
    switch (message.WParam.ToInt32())
                    {
                        
    case DBT_DEVICEARRIVAL:
                            SignalDeviceChange(UsbStateChange.Added);
                            
    break;

                        
    case DBT_DEVICEQUERYREMOVE:
                            
    // can intercept
                            break;

                        
    case DBT_DEVICEREMOVECOMPLETE:
                            SignalDeviceChange(UsbStateChange.Removed);
                            
    break;
                    }
                }
            }
            
    public event UsbStateChangedEventHandler StateChanged;

            
    private void SignalDeviceChange(UsbStateChange state)
            {

                
    if (StateChanged != null)
                {
                    StateChanged(
    new UsbStateChangedEventArgs(state));
                }
            }

        }
        
    public delegate void UsbStateChangedEventHandler(UsbStateChangedEventArgs e);
        
    public enum UsbStateChange
        {

            
    /// <summary>
            
    /// A device has been added and is now available.
            
    /// </summary>

            Added,


            
    /// <summary>
            
    /// A device is about to be removed;
            
    /// allows consumers to intercept and deny the action.
            
    /// </summary>

            Removing,


            
    /// <summary>
            
    /// A device has been removed and is no longer available.
            
    /// </summary>

            Removed
        }

        
    public class UsbStateChangedEventArgs : EventArgs
        {

            
    /// <summary>
            
    /// Initialize a new instance with the specified state and disk.
            
    /// </summary>
            
    /// <param name="state">The state change code.</param>
            
    /// <param name="disk">The USB disk description.</param>

            
    public UsbStateChangedEventArgs(UsbStateChange state)
            {
                
    this.State = state;
            }

            
    /// <summary>
            
    /// Gets the state change code.
            
    /// </summary>

            
    public UsbStateChange State
            {
                
    get;
                
    private set;
            }
        }
    }

    Override the WndProc(ref Message message) method is core code, which need winform support, so it can not be used in console application and WPF application.

    in the win from code, we can use it like 

     

      DriverWindow dw = new DriverWindow();
                dw.StateChanged 
    += new UsbStateChangedEventHandler(dw_StateChanged);

    The WPF version:

    代码
    using System.Runtime.InteropServices;
    using System;
    namespace Lenovo.Common.Devices
    {
        
    public class Win32
        {

            
    public const int DEVICE_NOTIFY_SERVICE_HANDLE = 1;
            
    public const int DEVICE_NOTIFY_WINDOW_HANDLE = 0;
            
    public const int DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 4;

            [Flags]
            
    public enum DEVICE_NOTIFY : uint
            {
                DEVICE_NOTIFY_WINDOW_HANDLE 
    = 0x00000000,
                DEVICE_NOTIFY_SERVICE_HANDLE 
    = 0x00000001,
                DEVICE_NOTIFY_ALL_INTERFACE_CLASSES 
    = 0x00000004
            }


            
    public const int SERVICE_CONTROL_STOP = 0x00000001;
            
    public const int SERVICE_CONTROL_DEVICEEVENT = 0x00000011;
            
    public const int SERVICE_CONTROL_SHUTDOWN = 0x00000005;
       
            
    /*DBT_DEVTYP_DEVICEINTERFACE 0x00000005
                Class of devices. This structure is a DEV_BROADCAST_DEVICEINTERFACE structure.
     
                DBT_DEVTYP_HANDLE   0x00000006
                File system handle. This structure is a DEV_BROADCAST_HANDLE structure.
     
                DBT_DEVTYP_OEM  0x00000000
                OEM- or IHV-defined device type. This structure is a DEV_BROADCAST_OEM structure.
     
                DBT_DEVTYP_PORT 0x00000003
                Port device (serial or parallel). This structure is a DEV_BROADCAST_PORT structure.
     
                DBT_DEVTYP_VOLUME 0x00000002
                Logical volume. This structure is a DEV_BROADCAST_VOLUME structure.
     
    */

            
    public const int DBT_DEVTYP_DEVICEINTERFACE = 0x00000005;
            
    public const int DBT_DEVTYP_HANDLE = 0x00000006;
            
    public const int DBT_DEVTYP_OEM = 0x00000000;
            
    public const int DBT_DEVTYP_PORT = 0x00000003;
            
    public const int DBT_DEVTYP_VOLUME = 0x00000002;


            
    public const int WM_DEVICECHANGE = 0x0219;                // device state change
            public const int DBT_DEVICEARRIVAL = 0x8000;            // detected a new device
            public const int DBT_DEVICEQUERYREMOVE = 0x8001;        // preparing to remove
            public const int DBT_DEVICEREMOVECOMPLETE = 0x8004;    // removed 
            public const int DBT_DEVNODES_CHANGED = 0x0007//A device has been added to or removed from the system.


            [DllImport(
    "user32.dll", SetLastError = true)]
            
    public static extern IntPtr RegisterDeviceNotification(IntPtr intPtr, IntPtr notificationFilter, uint flags);

            [DllImport(
    "user32.dll", CharSet = CharSet.Auto)]
            
    public static extern uint UnregisterDeviceNotification(IntPtr hHandle);

            [StructLayout(LayoutKind.Sequential, CharSet 
    = CharSet.Unicode)]
            
    public struct DEV_BROADCAST_DEVICEINTERFACE
            {
                
    public int dbcc_size;
                
    public int dbcc_devicetype;
                
    public int dbcc_reserved;
                
    //public IntPtr dbcc_handle;
                
    //public IntPtr dbcc_hdevnotify;
                [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 16)]
                
    public byte[] dbcc_classguid;
                [MarshalAs(UnmanagedType.ByValArray, SizeConst 
    = 128)]
                
    public Char[] dbcc_name;
                
    //public byte dbcc_data;
                
    //public byte dbcc_data1; 
            
            }

            [StructLayout(LayoutKind.Sequential)]
            
    public struct DEV_BROADCAST_HDR
            {
                
    public int dbcc_size;
                
    public int dbcc_devicetype;
                
    public int dbcc_reserved;
            }

            [StructLayout(LayoutKind.Sequential)]
            
    public struct DEV_BROADCAST_HANDLE
            {
                
    public int dbch_size;
                
    public int dbch_devicetype;
                
    public int dbch_reserved;
                
    public IntPtr dbch_handle;
                
    public IntPtr dbch_hdevnotify;
                
    public Guid dbch_eventguid;
                
    public long dbch_nameoffset;
                
    public Byte dbch_data;
                
    public Byte dbch_data1;
            }
        }
    }
    代码
    using System.Runtime.InteropServices;
    using System;

    namespace Lenovo.Common.Devices
    {
        
    public delegate void UsbStateChangedEventHandler(bool arrival);
        
    public class UsbDetector
        {
            
    public enum WM_DEVICECHANGE_WPPARAMS
            {
                DBT_DEVICEARRIVAL 
    = 0x8000,
                DBT_DEVICEQUERYREMOVE 
    = 0x8001,
                DBT_DEVICEREMOVECOMPLETE 
    = 0x8004,
                DBT_CONFIGCHANGECANCELED 
    = 0x19,
                DBT_CONFIGCHANGED 
    = 0x18,
                DBT_CUSTOMEVENT 
    = 0x8006,
                DBT_DEVICEQUERYREMOVEFAILED 
    = 0x8002,
                DBT_DEVICEREMOVEPENDING 
    = 0x8003,
                DBT_DEVICETYPESPECIFIC 
    = 0x8005,
                DBT_DEVNODES_CHANGED 
    = 0x7,
                DBT_QUERYCHANGECONFIG 
    = 0x17,
                DBT_USERDEFINED 
    = 0xFFFF
            }
            
    const int WM_DEVICECHANGE = 0x0219;

            
    public IntPtr HwndHandler(IntPtr hwnd, int msg, IntPtr wParam, IntPtr LParam, ref bool handled)
            {
                ProcessWinMessage(msg, wParam, LParam);
              
    //  handled = false;
                return IntPtr.Zero;
            }

            
    public event UsbStateChangedEventHandler StateChanged;

            
    public void ProcessWinMessage(int msg, IntPtr wParam, IntPtr LParam)
            {
              
    //  if ((msg == WM_DEVICECHANGE) && (LParam != IntPtr.Zero))
                if (msg == WM_DEVICECHANGE) 
                {
                    
    switch (wParam.ToInt32())
                    {
                        
    case Win32.DBT_DEVICEARRIVAL:
                            
    if (StateChanged != null)
                            {
                                StateChanged(
    true);
                            }
                            
    break;
                        
    case Win32.DBT_DEVICEREMOVECOMPLETE:
                            
    if (StateChanged != null)
                            {
                                StateChanged(
    false);
                            }
                            
    break;
                        
    case Win32.DBT_DEVNODES_CHANGED:
                            
    if (StateChanged != null)
                            {
                                StateChanged(
    false);
                            }
                            
    break;
                        
    default:
                            
    break;
                    }

                }
            }

           
    // private const string USBClassID = "c671678c-82c1-43f3-d700-0049433e9a4b";
            
    //http://msdn.microsoft.com/en-us/library/ff545972.aspx
            private const string USBClassID = "A5DCBF10-6530-11D2-901F-00C04FB951ED";
            
    public IntPtr RegisterDeviceNotification(IntPtr hwnd)
            {
                Win32.DEV_BROADCAST_DEVICEINTERFACE deviceInterface 
    = new Win32.DEV_BROADCAST_DEVICEINTERFACE();
                
    int size = Marshal.SizeOf(deviceInterface);
                deviceInterface.dbcc_size 
    = size;
            
    //    deviceInterface.dbcc_devicetype = Win32.DBT_DEVTYP_VOLUME;
                deviceInterface.dbcc_reserved = 0;
                
    //deviceInterface.dbcc_handle = hwnd;
                
    //deviceInterface.dbcc_hdevnotify = (IntPtr)0;
                deviceInterface.dbcc_classguid = new Guid(USBClassID).ToByteArray();
                IntPtr buffer 
    = IntPtr.Zero;
                buffer 
    = Marshal.AllocHGlobal(size);
                Marshal.StructureToPtr(deviceInterface, buffer, 
    true);
                IntPtr r 
    = IntPtr.Zero;
                r 
    = Win32.RegisterDeviceNotification(hwnd, buffer, 
                    (Int32)(Win32.DEVICE_NOTIFY.DEVICE_NOTIFY_ALL_INTERFACE_CLASSES  
                            
    | Win32.DEVICE_NOTIFY.DEVICE_NOTIFY_SERVICE_HANDLE | 
                            Win32.DEVICE_NOTIFY.DEVICE_NOTIFY_WINDOW_HANDLE)
                    );
                
                
    return r;
            }
        }
    }


     In the WPF application, we should register the DeviceNotification after the window is ready, so we should put them in the load event,

    in the constructor:

    代码
      UsbDetector usbDetector;
            
    public MainWindow()
            {
                InitializeComponent();
                usbDetector 
    = new UsbDetector();
                usbDetector.StateChanged 
    += new Lenovo.Common.Devices.UsbStateChangedEventHandler(usbDetector_StateChanged);

                
    this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
               
            }
      
    void MainWindow_Loaded(object sender, RoutedEventArgs e)
            {
                WindowInteropHelper interop 
    = new WindowInteropHelper(this);
                HwndSource hwndSource 
    = HwndSource.FromHwnd(interop.Handle);
                HwndSourceHook hool 
    = new HwndSourceHook(usbDetector.HwndHandler);
                hwndSource.AddHook(hool); ;
                usbDetector.RegisterDeviceNotification(interop.Handle);
            }

     
    void usbDetector_StateChanged(bool arrival)
            {
                
    if (arrival)
                    MessageBox.Show(
    "add");
                
    else
                    MessageBox.Show(
    "removed");
            }

    In generally, the wParam should be DBT_DEVICEARRIVAL or DBT_DEVICEREMOVECOMPLETE, but some time , it keep be the wParam =7 (DBT_DEVNODES_CHANGED) and LParam = 0, that is that the usb driver isn't correctly installed.

  • 相关阅读:
    storm环境搭建
    环境变量
    vmware tools安装及使用其实现与宿主机共享文件夹
    关于mysql中的count()函数
    centos7配置jdk8
    linux常用命令(随时更新中)
    ES中对索引的相关操作
    linux centos7下源码 tar安装mysql5.7.23(5.7以上均可试用)
    安装linux虚拟机配置静态ip(桥接模式,外部机器能够访问)
    安装linux虚拟机配置静态ip(NAT模式)
  • 原文地址:https://www.cnblogs.com/skyfei/p/1914821.html
Copyright © 2011-2022 走看看