我们在当前的应用程序中有几个进程.一个过程处理USB加载程序的检测和删除.处理检测和删除的代码如下.
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case Win32.WM_DEVICECHANGE: OnDeviceChange(ref m);
break;
}
base.WndProc(ref m);
}
private void OnDeviceChange(ref Message msg)
{
int wParam = (int)msg.WParam;
Win32.DEV_BROADCAST_VOLUME dbVol = new Win32.DEV_BROADCAST_VOLUME();
Win32.DEV_BROADCAST_HDR msgDevHeader = new Win32.DEV_BROADCAST_HDR();
const int DBT_DEVTYP_VOLUME = 0x00000002;
string loaderUpdates;
switch (wParam)
{
case Win32.DBT_DEVICEARRIVAL:
int devType = Marshal.ReadInt32(msg.LParam, 4);
if (devType == DBT_DEVTYP_VOLUME)
{
}
break;
case Win32.DBT_DEVICEREMOVECOMPLETE:
break;
}
}
Run Code Online (Sandbox Code Playgroud)
当我在visual studio环境中运行以调试模式处理USB加载程序的过程时,它会正确检测USB.但我仍然会收到多条消息.接收wparam值为"7"3次的消息,然后接收wparam值为"32768(0x8000/DBT_DEVICEARRIVAL)".这是正常的吗?
当我运行所有其他进程以及检测USB的进程时,似乎始终是仅接收到wparam值为"7"的消息.用wparam作为"7"5次接收meesage.没有wparam值为"(0x8000/DBT_DEVICEARRIVAL)"的消息.可能是什么问题呢?
感谢任何输入/解决方案.
问候Raju
据我所见,这是正常的。我在这里遇到了完全相同的问题。
您可以做两件事 - 为 DateTime.Now 设置一个 var,然后检查下一个到达时间,看看到达时间之间的时间差是否距上次发生事件的时间小于 x 秒(基本上存储您上次到达的时间)处理到达)
或者
您可以存储驱动器列表,如果事件处理与您已有的设备相同的设备,则可以忽略它。
但是,是的,因为 USB 设备通常将自己作为多个设备呈现给系统,所以它往往会发送多个设备插入。
我用来解决这个问题的另一件事是使用 WMI 的事件,通过观察程序来检测逻辑存储事件(__InstanceCreation ,目标为 Win32_LogicalDisk)
private void startMonitor()
{
while (serviceStarted)
{
ManagementEventWatcher watcher = new ManagementEventWatcher();
WqlEventQuery query = new WqlEventQuery("SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_LogicalDisk'");
watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
watcher.Query = query;
watcher.Start();
watcher.WaitForNextEvent();
}
Thread.CurrentThread.Abort();
}
Run Code Online (Sandbox Code Playgroud)
使用 EventArrived 处理程序...
private void watcher_EventArrived(object obj, EventArrivedEventArgs e)
{
var newEvent = e.NewEvent;
ManagementBaseObject targetInstance = (ManagementBaseObject)newEvent.GetPropertyValue("TargetInstance");
string drivename = targetInstance.GetPropertyValue("Name").ToString();
Run Code Online (Sandbox Code Playgroud)
Drivename 最终实际上是驱动器号,例如 D: 或其他......
缺点是应用程序需要以本地 WMI 范围的正确权限运行,并且比被动处理窗口消息稍微密集一些。
| 归档时间: |
|
| 查看次数: |
4733 次 |
| 最近记录: |