在 Windows 上检测外部设备插入
Detect external devices insertion on Windows
对于如何将用户插入设备(USB、HID 等)的事件通知我的 C++ 应用程序,我有点困惑。未定义应用程序类型。我正在尝试使用 console/message-only/service 个示例应用程序,但没有结果。我正在使用 VS2015 和 Windows 10.
我发现有多种方法可以处理它:
- 像 here 一样使用 WMI。但我实际上无法理解 WMI 在哪里。
使用RegisterDeviceNotification and WM_DEVICECHANGE. As far as I can understand, there is no way to do that for the console applications, only for once with the GUI (real window) or for the message-only window. I've tried the last one with the example from this answer but my app doesn't receive any notifications when I plug in my USB flash drive. I've found this answer(来自与上述答案相同的问题)并尝试使用 ChangeWindowMessageFilterEx() 函数和 user32.dll 中的 GetProcAddress 来加载它而无需连接 dll 到我的应用程序是这样的:
BOOL InitInstance(HWND hWnd)
{
HMODULE hDll = GetModuleHandle(TEXT("user32.dll"));
if (hDll)
{
typedef BOOL(WINAPI *MESSAGEFILTERFUNCEX)(HWND hWnd, UINT message, DWORD action, VOID* pChangeFilterStruct);
const DWORD MSGFLT_ALLOW = 1;
MESSAGEFILTERFUNCEX ChangeWindowMessageFilterEx= (MESSAGEFILTERFUNCEX)::GetProcAddress(hDll, "ChangeWindowMessageFilterEx");
if (ChangeWindowMessageFilterEx) return func(hWnd, WM_COPYDATA, MSGFLT_ALLOW, NULL);
}
return FALSE; }
而这个函数的用法是:
hWnd = CreateWindowEx(0, CLS_NAME, "DevNotifWnd", WS_ICONIC,
0, 0, CW_USEDEFAULT, 0, HWND_MESSAGE,
NULL, GetModuleHandle(0), (void*)&guid);
InitInstance(hWnd);
但是没有效果。
使用 while(true){...}
循环并调用适当的 Win API 函数,如 this answer 中那样。但是这种方式似乎不是我的问题的完美解决方案。
我的问题是:
- 谁能告诉我最好的方法是什么?如果它是第二个带有 RegisterDeviceNotification 的应用程序,为什么它在仅消息 window 应用程序的情况下不起作用?
- 还有其他方法吗?如果没有,我可以做些什么,例如,当安装了某些软件时通知应用程序?
如有任何意见,我们将不胜感激。
所以我终于找到了问题的答案。
问题出在我为 NotificationFilter
提供的 GUID。所以我将其设置为使用以下代码接收来自所有设备的通知:
DEV_BROADCAST_DEVICEINTERFACE通知过滤器;
ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
// No need to set up dbcc_classguid as it is ignored when
// DEVICE_NOTIFY_ALL_INTERFACE_CLASSES is setted (see line down below)
HDEVNOTIFY dev_notify = RegisterDeviceNotification(hwnd, &NotificationFilter, DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
至于应用程序可以注册的 windows 中的其他类型的通知,我只找到一个 partially deprecated list of all Win32 API functions,在那里我发现了一些新的 Ctrl 通知+F 搜索 :)
希望这可以节省一些人的时间。
对于如何将用户插入设备(USB、HID 等)的事件通知我的 C++ 应用程序,我有点困惑。未定义应用程序类型。我正在尝试使用 console/message-only/service 个示例应用程序,但没有结果。我正在使用 VS2015 和 Windows 10.
我发现有多种方法可以处理它:
- 像 here 一样使用 WMI。但我实际上无法理解 WMI 在哪里。
使用RegisterDeviceNotification and WM_DEVICECHANGE. As far as I can understand, there is no way to do that for the console applications, only for once with the GUI (real window) or for the message-only window. I've tried the last one with the example from this answer but my app doesn't receive any notifications when I plug in my USB flash drive. I've found this answer(来自与上述答案相同的问题)并尝试使用 ChangeWindowMessageFilterEx() 函数和 user32.dll 中的 GetProcAddress 来加载它而无需连接 dll 到我的应用程序是这样的:
BOOL InitInstance(HWND hWnd) { HMODULE hDll = GetModuleHandle(TEXT("user32.dll")); if (hDll) { typedef BOOL(WINAPI *MESSAGEFILTERFUNCEX)(HWND hWnd, UINT message, DWORD action, VOID* pChangeFilterStruct); const DWORD MSGFLT_ALLOW = 1; MESSAGEFILTERFUNCEX ChangeWindowMessageFilterEx= (MESSAGEFILTERFUNCEX)::GetProcAddress(hDll, "ChangeWindowMessageFilterEx"); if (ChangeWindowMessageFilterEx) return func(hWnd, WM_COPYDATA, MSGFLT_ALLOW, NULL); } return FALSE; }
而这个函数的用法是:
hWnd = CreateWindowEx(0, CLS_NAME, "DevNotifWnd", WS_ICONIC, 0, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, NULL, GetModuleHandle(0), (void*)&guid); InitInstance(hWnd);
但是没有效果。
使用
while(true){...}
循环并调用适当的 Win API 函数,如 this answer 中那样。但是这种方式似乎不是我的问题的完美解决方案。
我的问题是:
- 谁能告诉我最好的方法是什么?如果它是第二个带有 RegisterDeviceNotification 的应用程序,为什么它在仅消息 window 应用程序的情况下不起作用?
- 还有其他方法吗?如果没有,我可以做些什么,例如,当安装了某些软件时通知应用程序?
如有任何意见,我们将不胜感激。
所以我终于找到了问题的答案。
问题出在我为
NotificationFilter
提供的 GUID。所以我将其设置为使用以下代码接收来自所有设备的通知: DEV_BROADCAST_DEVICEINTERFACE通知过滤器;ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; // No need to set up dbcc_classguid as it is ignored when // DEVICE_NOTIFY_ALL_INTERFACE_CLASSES is setted (see line down below) HDEVNOTIFY dev_notify = RegisterDeviceNotification(hwnd, &NotificationFilter, DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
至于应用程序可以注册的 windows 中的其他类型的通知,我只找到一个 partially deprecated list of all Win32 API functions,在那里我发现了一些新的 Ctrl 通知+F 搜索 :)
希望这可以节省一些人的时间。