如何在 Windows 进程回调中断开连接时获取设备信息(硬件 ID)?
How to get device info (hardware IDs) on disconnect in Windows process callback?
使用 Windows 设备更改过程回调,我可以在设备到达时设置句柄,这让我可以通过简单的方式查看它的设备属性,例如硬件 ID,而无需执行任何设备枚举。
然而,在 "device disconnect" 上收到的句柄无效,这似乎是正确的,因为设备不再连接,但我无法查看设备属性。有什么方法可以继续使用手柄吗?
DEV_BROADCAST_HDR* devHDR = reinterpret_cast<DEV_BROADCAST_HDR*>(lParam);
if (devHDR->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
{
DEV_BROADCAST_DEVICEINTERFACE* devInterface = reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(lParam);
DeviceHandle = CreateFile(devInterface->dbcc_name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
if(DeviceHandle == != INVALID_HANDLE_VALUE){
// arrive gets here
} else {
// disconnect gets here
}
}
基本上,由于无法在断开连接时获得有效句柄,因此无法从 DEV_BROADCAST_DEVICEINTERFACE 结构中获取硬件 ID 和其他数据。还有其他方法可以在断开连接时获取设备硬件 ID 吗?
当设备连接时,将断开连接时需要的信息存储在地图中,您可以在地图上使用设备独有的东西作为密钥。
当设备断开连接时,使用您在断开连接事件中获得的密钥在地图中查找信息,然后删除该条目。
示例:
using String = std::basic_string<TCHAR>;
// a struct with all the properties you'd like to use on disconnect
struct device_info {
CHANGER_PRODUCT_DATA cpd; // just an example
String something;
};
int main() {
// a map where the device_name is the key and device_info the value
std::unordered_map<String, device_info> devices;
{ // on connect, create a device_info struct and fill it with the info you need on
// disconnect
DEV_BROADCAST_DEVICEINTERFACE* devInterface =
reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(lParam);
String new_dev_name { devInterface->dbcc_name };
device_info di{}; // store what you need from the opened device here
// and put it in the map
devices.emplace(new_dev_name, di);
}
{ // on disconnect, find the entry in the map using the disconnected device_name
DEV_BROADCAST_DEVICEINTERFACE* devInterface =
reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(lParam);
String disc_dev_name{ devInterface->dbcc_name };
auto fit = devices.find(disc_dev_name);
if (fit != devices.end()) {
// we found the device, extract it
device_info disc_di = fit->second;
// and erase it from the map
devices.erase(fit);
std::wcout << "\"" << disc_di.something << "\" disconnected\n";
}
}
}
你的方法不对。
您必须先检查 wParam 并测试是否 == DBT_DEVICEARRIVAL 和 == DBT_DEVICEREMOVECOMPLETE
在DBT_DEVICEREMOVECOMPLETE测试中,你会得到lParam填充得到DEV_BROADCAST_HANDLE
使用 Windows 设备更改过程回调,我可以在设备到达时设置句柄,这让我可以通过简单的方式查看它的设备属性,例如硬件 ID,而无需执行任何设备枚举。
然而,在 "device disconnect" 上收到的句柄无效,这似乎是正确的,因为设备不再连接,但我无法查看设备属性。有什么方法可以继续使用手柄吗?
DEV_BROADCAST_HDR* devHDR = reinterpret_cast<DEV_BROADCAST_HDR*>(lParam);
if (devHDR->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
{
DEV_BROADCAST_DEVICEINTERFACE* devInterface = reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(lParam);
DeviceHandle = CreateFile(devInterface->dbcc_name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
if(DeviceHandle == != INVALID_HANDLE_VALUE){
// arrive gets here
} else {
// disconnect gets here
}
}
基本上,由于无法在断开连接时获得有效句柄,因此无法从 DEV_BROADCAST_DEVICEINTERFACE 结构中获取硬件 ID 和其他数据。还有其他方法可以在断开连接时获取设备硬件 ID 吗?
当设备连接时,将断开连接时需要的信息存储在地图中,您可以在地图上使用设备独有的东西作为密钥。
当设备断开连接时,使用您在断开连接事件中获得的密钥在地图中查找信息,然后删除该条目。
示例:
using String = std::basic_string<TCHAR>;
// a struct with all the properties you'd like to use on disconnect
struct device_info {
CHANGER_PRODUCT_DATA cpd; // just an example
String something;
};
int main() {
// a map where the device_name is the key and device_info the value
std::unordered_map<String, device_info> devices;
{ // on connect, create a device_info struct and fill it with the info you need on
// disconnect
DEV_BROADCAST_DEVICEINTERFACE* devInterface =
reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(lParam);
String new_dev_name { devInterface->dbcc_name };
device_info di{}; // store what you need from the opened device here
// and put it in the map
devices.emplace(new_dev_name, di);
}
{ // on disconnect, find the entry in the map using the disconnected device_name
DEV_BROADCAST_DEVICEINTERFACE* devInterface =
reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(lParam);
String disc_dev_name{ devInterface->dbcc_name };
auto fit = devices.find(disc_dev_name);
if (fit != devices.end()) {
// we found the device, extract it
device_info disc_di = fit->second;
// and erase it from the map
devices.erase(fit);
std::wcout << "\"" << disc_di.something << "\" disconnected\n";
}
}
}
你的方法不对。
您必须先检查 wParam 并测试是否 == DBT_DEVICEARRIVAL 和 == DBT_DEVICEREMOVECOMPLETE
在DBT_DEVICEREMOVECOMPLETE测试中,你会得到lParam填充得到DEV_BROADCAST_HANDLE