惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
B
Blog RSS Feed
Apple Machine Learning Research
Apple Machine Learning Research
D
Darknet – Hacking Tools, Hacker News & Cyber Security
V2EX - 技术
V2EX - 技术
Security Archives - TechRepublic
Security Archives - TechRepublic
Cisco Talos Blog
Cisco Talos Blog
T
Tor Project blog
博客园 - 司徒正美
T
The Blog of Author Tim Ferriss
J
Java Code Geeks
宝玉的分享
宝玉的分享
小众软件
小众软件
博客园_首页
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Project Zero
Project Zero
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Spread Privacy
Spread Privacy
I
InfoQ
博客园 - 叶小钗
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
罗磊的独立博客
M
MIT News - Artificial intelligence
爱范儿
爱范儿
The Cloudflare Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
T
Tenable Blog
S
Securelist
N
News and Events Feed by Topic
Simon Willison's Weblog
Simon Willison's Weblog
Webroot Blog
Webroot Blog
The Hacker News
The Hacker News
O
OpenAI News
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Palo Alto Networks Blog
C
CERT Recently Published Vulnerability Notes
PCI Perspectives
PCI Perspectives
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Threat Research - Cisco Blogs
L
LINUX DO - 热门话题
I
Intezer
Scott Helme
Scott Helme
Recent Commits to openclaw:main
Recent Commits to openclaw:main
C
Cybersecurity and Infrastructure Security Agency CISA
Google Online Security Blog
Google Online Security Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
S
Security Affairs
AI
AI
AWS News Blog
AWS News Blog
Security Latest
Security Latest

博客园 - skyfei

Xcode 文档注释方法 查看iOS模拟器应用的沙箱文件 Show in Finder OC代码 C# x86应用x64系统上读取x64位应用的注册表 Make webclient support upload the large file which are larger than 1G Shortcut key for WPF get Android information with adb, the build version Decodes a QuotedPrintable encoded string [转] 线程同步 C# 常见面试题(2) 转:C# Interview Questions Openxml: 导出excel 设置 cell的格式 - skyfei OpenXML: excel 插入BarChart图表 OpenXML: Asp.net利用OpenXML 导出Excel. TRIGGERS :Cannot use text, ntext, or image columns in the 'inserted' and ' deleted' tables. 'String or binary data would be truncated' error message .net Create Excel 2007 file with open xml 利用.Net Framework2.0 zip压缩、解压 string 数据 C#中文和UNICODE字符转换方法 - skyfei - 博客园
C# USB Detection - winform and WPF
skyfei · 2010-12-23 · via 博客园 - skyfei

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.

posted on 2010-12-23 14:41  skyfei  阅读(3798)  评论()    收藏  举报