我们在当前的应用程序中有几个进程。一个过程处理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;
}
}
当我在visual studio环境中运行以调试模式处理USB加载程序的过程时,它会正确检测USB。但仍然会收到多条消息。接收wparam值为“7”3次的消息,然后接收wparam值为“32768(0x8000 / DBT_DEVICEARRIVAL)”。这是正常的吗?
当我运行所有其他进程以及检测USB的进程时,似乎始终是仅接收到wparam值为“7”的消息。用wparam作为“7”5次接收meesage。没有wparam值为“(0x8000 / DBT_DEVICEARRIVAL)”的消息。 可能是什么问题?
感谢任何输入/解决方案。
此致 拉朱
答案 0 :(得分:3)
从我所见,这是正常的。我在这里遇到了完全相同的问题。
你可以做两件事 - 为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();
}
使用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();
Drivename最终实际上是驱动器号,例如D:或其他......
缺点是应用程序需要使用本地WMI范围的正确权限运行,并且比被动处理窗口消息稍微强一些。