在 Windows 上检测外部设备插入

Detect external devices insertion on Windows

对于如何将用户插入设备(USB、HID 等)的事件通知我的 C++ 应用程序,我有点困惑。未定义应用程序类型。我正在尝试使用 console/message-only/service 个示例应用程序,但没有结果。我正在使用 VS2015 和 Windows 10.

我发现有多种方法可以处理它:

  1. here 一样使用 WMI。但我实际上无法理解 WMI 在哪里。
  2. 使用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);
    

    但是没有效果。

  3. 使用 while(true){...} 循环并调用适当的 Win API 函数,如 this answer 中那样。但是这种方式似乎不是我的问题的完美解决方案。

我的问题是:

  1. 谁能告诉我最好的方法是什么?如果它是第二个带有 RegisterDeviceNotification 的应用程序,为什么它在仅消息 window 应用程序的情况下不起作用?
  2. 还有其他方法吗?如果没有,我可以做些什么,例如,当安装了某些软件时通知应用程序?

如有任何意见,我们将不胜感激。

所以我终于找到了问题的答案。

  1. 问题出在我为 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);
    
  2. 至于应用程序可以注册的 windows 中的其他类型的通知,我只找到一个 partially deprecated list of all Win32 API functions,在那里我发现了一些新的 Ctrl 通知+F 搜索 :)

希望这可以节省一些人的时间。