监听USB设备的插入和弹出
2012-03-07 12:38
405 查看
当USB设备插入或者弹出时,Windows会产生一条全局消息:WM_DEVICECHANGE
我们需要做的是,获得这条消息的wParam参数,如果为DBT_DEVICEARRIVAL则表示有设备插入并可用,
如果是DBT_DEVICEREMOVECOMPLETE则表示有设备已经移除。再查看lParam参数为DBT_DEVTYP_VOLUME时,
就可以取出DEV_BROADCAST_VOLUME结构的卷号dbcv_unitmask,就知道是哪个卷被插入或者弹出。
代码片段如下:
现在,你可以在你的UI线程上创建一个DriveDetector对象,监听DeviceArrived和DeviceRemoved事件。
然后通过该对象WndProc方法,传递UI线程上的消息。WPF程序可以直接用HwndSource对象AddHook,此方法的签名
与HwndSourceHook委托相同。WinForm程序也没关系,override窗口的void WndProc(ref Message m)方法,按
DriveDetector对象的WndProc签名格式,将m数据传入,或者干脆自己写个WinForm版本的。
我的演示代码效果图如下:(注,上述代码未提供显示代码,请自己编写)
另外,关于磁盘容量的监视可以使用FileSystemWatcher对象。
请参考:http://msdn.microsoft.com/zh-cn/library/cc437966.aspx
摘取代码如下:
原文地址:http://daimajishu.iteye.com/blog/1087538
我们需要做的是,获得这条消息的wParam参数,如果为DBT_DEVICEARRIVAL则表示有设备插入并可用,
如果是DBT_DEVICEREMOVECOMPLETE则表示有设备已经移除。再查看lParam参数为DBT_DEVTYP_VOLUME时,
就可以取出DEV_BROADCAST_VOLUME结构的卷号dbcv_unitmask,就知道是哪个卷被插入或者弹出。
代码片段如下:
using System; using System.Runtime.InteropServices; /// <summary> /// 监听设备的插入和拔出 /// </summary> public class DriveDetector { /// <summary> /// 设备插入事件 /// </summary> public event EventHandler<DriveDectctorEventArgs> DeviceArrived = null; /// <summary> /// 设备拔出事件 /// </summary> public event EventHandler<DriveDectctorEventArgs> DeviceRemoved = null; /// <summary> /// 消息处理(HwndSourceHook委托的签名) /// </summary> /// <param name="hwnd"></param> /// <param name="msg"></param> /// <param name="wParam"></param> /// <param name="lParam"></param> /// <param name="handled"></param> /// <returns></returns> public IntPtr WndProc( IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (msg == NativeConstants.WM_DEVICECHANGE) { #warning USB设备检测目前只支持32位系统) switch (wParam.ToInt32()) { case NativeConstants.DBT_DEVICEARRIVAL: { var devType = Marshal.ReadInt32(lParam, 4); if (devType == NativeConstants.DBT_DEVTYP_VOLUME) { var drive = GetDrive(lParam); if (DeviceArrived != null) { var args = new DriveDectctorEventArgs(drive); DeviceArrived(this, args); //触发设备插入事件 } } } break; case NativeConstants.DBT_DEVICEREMOVECOMPLETE: { var devType = Marshal.ReadInt32(lParam, 4); if (devType == NativeConstants.DBT_DEVTYP_VOLUME) { var drive = GetDrive(lParam); if (DeviceRemoved != null) { var args = new DriveDectctorEventArgs(drive); DeviceRemoved(this, args); } } } break; } } return IntPtr.Zero; } private static string GetDrive(IntPtr lParam) { var volume = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(lParam, typeof(DEV_BROADCAST_VOLUME)); var letter = GetLetter(volume.dbcv_unitmask); return string.Format("{0}:\\", letter); } /// <summary> /// 获得盘符 /// </summary> /// <param name="dbcvUnitmask"> /// 1 = A /// 2 = B /// 4 = C... /// </param> /// <returns>结果是A~Z的任意一个字符或者为'?'</returns> private static char GetLetter(uint dbcvUnitmask) { const char nona = '?'; const string drives = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; if (dbcvUnitmask == 0) return nona; var i = 0; var pom = dbcvUnitmask >> 1; while (pom != 0) { pom = pom >> 1; i++; } if (i < drives.Length) return drives[i]; return nona; } /* private static void GetLetterTest() { for (int i = 0; i < 67108864; i++) { Console.WriteLine("{0} - {1}", i, GetLetter((uint)i)); i = i << 1; } //0 - ? //1 - A //3 - B //7 - C //15 - D //31 - E //63 - F //127 - G //255 - H //511 - I //1023 - J //2047 - K //4095 - L //8191 - M //16383 - N //32767 - O //65535 - P //131071 - Q //262143 - R //524287 - S //1048575 - T //2097151 - U //4194303 - V //8388607 - W //16777215 - X //33554431 - Y //67108863 - Z }*/ /// <summary> /// 设备插入或拔出事件 /// </summary> public class DriveDectctorEventArgs : EventArgs { /// <summary> /// 获得设备卷标 /// </summary> public string Drive { get; private set; } public DriveDectctorEventArgs(string drive) { Drive = drive ?? string.Empty; } } #region Win32 API public partial class NativeConstants { /// WM_DEVICECHANGE -> 0x0219 public const int WM_DEVICECHANGE = 537; /// BROADCAST_QUERY_DENY -> 0x424D5144 //public const int BROADCAST_QUERY_DENY = 1112363332; //public const int DBT_DEVTYP_DEVICEINTERFACE = 5; //public const int DBT_DEVTYP_HANDLE = 6; public const int DBT_DEVICEARRIVAL = 0x8000; // system detected a new device //public const int DBT_DEVICEQUERYREMOVE = 0x8001; // Preparing to remove (any program can disable the removal) public const int DBT_DEVICEREMOVECOMPLETE = 0x8004; // removed public const int DBT_DEVTYP_VOLUME = 0x00000002; // drive type is logical volume } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public struct DEV_BROADCAST_VOLUME { /// DWORD->unsigned int public uint dbcv_size; /// DWORD->unsigned int public uint dbcv_devicetype; /// DWORD->unsigned int public uint dbcv_reserved; /// DWORD->unsigned int public uint dbcv_unitmask; /// WORD->unsigned short public ushort dbcv_flags; } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public struct OVERLAPPED { /// ULONG_PTR->unsigned int public uint Internal; /// ULONG_PTR->unsigned int public uint InternalHigh; /// Anonymous_7416d31a_1ce9_4e50_b1e1_0f2ad25c0196 public Anonymous_7416d31a_1ce9_4e50_b1e1_0f2ad25c0196 Union1; /// HANDLE->void* public System.IntPtr hEvent; } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Explicit)] public struct Anonymous_7416d31a_1ce9_4e50_b1e1_0f2ad25c0196 { /// Anonymous_ac6e4301_4438_458f_96dd_e86faeeca2a6 [System.Runtime.InteropServices.FieldOffsetAttribute(0)] public Anonymous_ac6e4301_4438_458f_96dd_e86faeeca2a6 Struct1; /// PVOID->void* [System.Runtime.InteropServices.FieldOffsetAttribute(0)] public System.IntPtr Pointer; } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public struct Anonymous_ac6e4301_4438_458f_96dd_e86faeeca2a6 { /// DWORD->unsigned int public uint Offset; /// DWORD->unsigned int public uint OffsetHigh; } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public struct SECURITY_ATTRIBUTES { /// DWORD->unsigned int public uint nLength; /// LPVOID->void* public System.IntPtr lpSecurityDescriptor; /// BOOL->int [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)] public bool bInheritHandle; } #endregion }
现在,你可以在你的UI线程上创建一个DriveDetector对象,监听DeviceArrived和DeviceRemoved事件。
然后通过该对象WndProc方法,传递UI线程上的消息。WPF程序可以直接用HwndSource对象AddHook,此方法的签名
与HwndSourceHook委托相同。WinForm程序也没关系,override窗口的void WndProc(ref Message m)方法,按
DriveDetector对象的WndProc签名格式,将m数据传入,或者干脆自己写个WinForm版本的。
我的演示代码效果图如下:(注,上述代码未提供显示代码,请自己编写)
另外,关于磁盘容量的监视可以使用FileSystemWatcher对象。
请参考:http://msdn.microsoft.com/zh-cn/library/cc437966.aspx
摘取代码如下:
using System; using System.IO; using System.Security.Permissions; public class Watcher { public static void Main() { Run(); } [PermissionSet(SecurityAction.Demand, Name="FullTrust")] public static void Run() { string[] args = System.Environment.GetCommandLineArgs(); // If a directory is not specified, exit program. if(args.Length != 2) { // Display the proper way to call the program. Console.WriteLine("Usage: Watcher.exe (directory)"); return; } // Create a new FileSystemWatcher and set its properties. FileSystemWatcher watcher = new FileSystemWatcher(); watcher.Path = args[1]; /* Watch for changes in LastAccess and LastWrite times, and the renaming of files or directories. */ watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName; // Only watch text files. //watcher.Filter = "*.txt"; watcher.IncludeSubdirectories=true; // Add event handlers. watcher.Changed += new FileSystemEventHandler(OnChanged); watcher.Created += new FileSystemEventHandler(OnChanged); watcher.Deleted += new FileSystemEventHandler(OnChanged); watcher.Renamed += new RenamedEventHandler(OnRenamed); // Begin watching. watcher.EnableRaisingEvents = true; // Wait for the user to quit the program. Console.WriteLine("Press \'q\' to quit the sample."); while(Console.Read()!='q'); } // Define the event handlers. private static void OnChanged(object source, FileSystemEventArgs e) { // Specify what is done when a file is changed, created, or deleted. Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType); } private static void OnRenamed(object source, RenamedEventArgs e) { // Specify what is done when a file is renamed. Console.WriteLine("File: {0} renamed to {1}", e.OldFullPath, e.FullPath); } }
原文地址:http://daimajishu.iteye.com/blog/1087538
相关文章推荐
- QT 监听 USB 设备 插入、拔出动作
- c# 获取移动硬盘信息、监听移动设备的弹出与插入事件
- c# 获取移动硬盘信息、监听移动设备的弹出与插入事件
- Android插入USB设备,自动弹出提示运行apk
- Android系统插入USB设备自动授权不弹出对话框
- QT编程--监听USB设备拔出和插入。
- PyQt4实现USB设备插入到弹出的检测(Windows)
- Win7插入USB移动存储设备没反应不弹出自动播放窗口
- Android插入USB设备,自动弹出提示运行apk
- 关于解决插入USB设备蓝屏的思路【转】
- windows下弹出指定USB设备的小程序
- Android的Usb设备的监听(Dev)外设端口的判定以及耳机的插拔
- USB设备“弹出”与“安全删除”的区别
- 两种检测USB设备插入和移除的方法(Ver 2)
- Win7系统移除USB弹出windows 无法停用怎么办 Win7无法安全移除USB设备的解决方法
- Java实现监听USB插入
- 如何让内置sdcard不弹出 存储设备插入拔出消息。
- VC识别有USB存储设备插入
- 黑苹果各种奇怪故障,插入USB设备引导失败故障。
- <C/C++>USB设备注册与插拔监听