我通常通过监视器WM_DEVICECHANGE消息检测USB设备插入和移除事件。 在Windows XP中,当USB插入事件发生时,消息如下:
WM_DEVICECHANGE
WParam = DBT_DEVICEARRIVAL, devType = DBT_DEVTYP_DEVICEINTERFACE
WM_DEVICECHANGE
WParam = DBT_DEVICEARRIVAL, devType = DBT_DEVTYP_VOLUME
但是现在我使用的是Windows 8.1,对于同一事件,消息如下:
WM_DEVICECHANGE
WParam = **DBT_DEVICEARRIVAL**, devType = DBT_DEVTYP_DEVICEINTERFACE
WM_DEVICECHANGE
WParam = **DBT_DEVICEREMOVECOMPLETE**, devType = DBT_DEVTYP_DEVICEINTERFACE
WM_DEVICECHANGE
WParam = DBT_DEVICEARRIVAL, devType = DBT_DEVTYP_DEVICEINTERFACE
WM_DEVICECHANGE
WParam = DBT_DEVICEARRIVAL, devType = DBT_DEVTYP_VOLUME
我的问题是:
答案 0 :(得分:0)
当USB设备连接到设备或从中移除USB设备时,系统会生成前两条消息DBT_DEVICEARRIVAL
和DBT_DEVICEREMOVECOMPLETE
。通过监听这些消息,您的代码可以具有“即插即用”功能:当连接新设备时,可以执行某些操作;当它被移除时做其他事情......我不知道Win 8与以前的版本有什么不同,但有几个例子说明如何检测USB'设备更改'事件给出here,{{ 3}}和here。
我的解决方案如下,但基本上您无法听取WM_DEVICECHANGE
消息,因此您需要覆盖WinForms
的{{1}}组件。关于“设备管理”的MSDN文章在这里:here
正如您将看到的,它是所有非托管代码。
WndProc()
然后,在“接收者”(订阅和使用我们的#pragma once
#include <Windows.h> // Declares required datatypes.
#include <Dbt.h> // Required for WM_DEVICECHANGE messages.
#include <initguid.h> // Required for DEFINE_GUID definition (see below).
namespace USBComms
{
using namespace System;
using namespace System::Runtime::InteropServices;
using namespace System::Windows;
using namespace System::Windows::Forms;
// This function is required for receieving WM_DEVICECHANGE messages.
// Note: name is remapped "RegisterDeviceNotificationUM"
[DllImport("user32.dll" , CharSet = CharSet::Unicode, EntryPoint="RegisterDeviceNotification")]
extern "C" HDEVNOTIFY WINAPI RegisterDeviceNotificationUM(
HANDLE hRecipient,
LPVOID NotificationFilter,
DWORD Flags);
// Generic guid for usb devices (see e.g. http://msdn.microsoft.com/en-us/library/windows/hardware/ff545972%28v=vs.85%29.aspx).
// Note: GUIDs are device and OS specific and may require modification. Using the wrong guid will cause notification to fail.
// You may have to tinker with your device to find the appropriate GUID. "hid.dll" has a function `HidD_GetHidGuid' that returns
// "the device interfaceGUID for HIDClass devices" (see http://msdn.microsoft.com/en-us/library/windows/hardware/ff538924%28v=vs.85%29.aspx).
// However, testing revealed it does not always return a useful value. The GUID_DEVINTERFACE_USB_DEVICE value, defined as
// {A5DCBF10-6530-11D2-901F-00C04FB951ED}, has worked with cell phones, thumb drives, etc. For more info, see e.g.
// http://msdn.microsoft.com/en-us/library/windows/hardware/ff553426%28v=vs.85%29.aspx.
DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED);
/// <summary>
/// Declare a delegate for the notification event handler.
/// </summary>
/// <param name="sender">The object where the event handler is attached.</param>
/// <param name="e">The event data.</param>
public delegate void NotificationEventHandler(Object^ sender, EventArgs^ e);
/// <summary>
/// Class that generetaes USB Device Change notification events.
/// </summary>
/// <remarks>
/// A Form is not necessary. Any type wherein you can override WndProc() can be used.
/// </remarks>
public ref class EventNotifier : public Control
{
private:
/// <summary>
/// Raises the NotificationEvent.
/// </summary>
/// <param name="e">The event data.</param>
void RaiseNotificationEvent(EventArgs^ e) {
NotificationEvent(this, e);
}
protected:
/// <summary>
/// Overrides the base class WndProc method.
/// </summary>
/// <param name="message">The Windows Message to process. </param>
/// <remarks>
/// This method receives Windows Messages (WM_xxxxxxxxxx) and
/// raises our NotificationEvent as appropriate. Here you should
/// add any message filtering (e.g. for the WM_DEVICECHANGE) and
/// preprocessing before raising the event (or not).
/// </remarks>
virtual void WndProc(Message% message) override {
if(message.Msg == WM_DEVICECHANGE)
{
RaiseNotificationEvent(EventArgs::Empty);
}
__super::WndProc(message);
}
public:
/// <summary>
/// Creates a new instance of the EventNotifier class.
/// </summary>
EventNotifier(void) {
RequestNotifications(this->Handle); // Register ourselves as the Windows Message processor.
}
/// <summary>
/// Registers an object, identified by the handle, for
/// Windows WM_DEVICECHANGE messages.
/// </summary>
/// <param name="handle">The object's handle.</param>
bool RequestNotifications(IntPtr handle) {
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_reserved = 0;
NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
return RegisterDeviceNotificationUM((HANDLE)handle, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE) != NULL;
}
/// <summary>
/// Defines the notification event.
/// </summary>
virtual event NotificationEventHandler^ NotificationEvent;
};
}
的对象)中,您所要做的就是:
NotificationEvent