我正在将一个应用程序从DirectInput切换到RawInput来处理游戏手柄,我想为每个游戏手柄提供一个人类可读的描述。理想的情况是出现在设备管理器中的设备文本,但USB产品描述也可以。任何方法都应该在没有管理员权限的情况下工作。
到目前为止,我找到了一个set of clues:在HKLM\SYSTEM\CurrentControlSet\Control\MediaProperties\PrivateProperties\Joystick\OEM
下的注册表中似乎有一个文本字段,它与DirectInput提供的名称相同。这并不完美-我有一个游戏手柄,它以英文出现在设备管理器中,但在注册表中显示为氀。
有没有办法从WM_INPUT
提供的句柄转到设备管理器描述?HidD_GetProductString
看起来很有希望,但我不知道如何从RawInput句柄获得Hid顶级集合句柄。
编辑:我有一个设备实例路径(例如:\\?\HID#VID_1267&PID_A001#8&1d630df6&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
,这可能足以从SetupAPI中提取我需要的信息。有没有人知道如何在给定实例路径的情况下达到此目的?
发布于 2012-11-19 06:18:05
我一直有类似的问题,我相信我找到了一个潜在的解决方案。
似乎您必须使用RawInput通过调用GetRawInputDeviceInfo
提供的名称来调用CreateFile
,并将RIDI_DEVICENAME
作为uiCommand
参数的参数。这将为您提供设备的句柄,您可以使用该句柄调用HidD_GetProductString
。
wchar_t DeviceName[126];
HANDLE HIDHandle = CreateFile(RawInputDeviceName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
if(HIDHandle)
{
BOOLEAN Result = HidD_GetProductString(HIDHandle, DeviceName, sizeof(wchar_t) * 126);
CloseHandle(HIDHandle);
}
然而,似乎HidD_GetProductString
在我的系统上连接的大多数设备上都失败了,似乎只有我的USB键盘和网络摄像头成功了。我的USB鼠标没有成功。我还没有发现为什么会这样,但也许我的进步会对你有所帮助。
发布于 2015-06-02 01:17:46
发布于 2020-10-12 23:48:56
对于HID设备,您可以使用HidD_GetProductString
,但键盘和鼠标在Windows上不能通过HID API获得,并公开为单独的设备类型:GUID_DEVINTERFACE_KEYBOARD/GUID_DEVINTERFACE_MOUSE (出于安全原因,它们不能由用户模式应用程序直接读取)。
您可以从设备界面符号链接中获取他们的设备信息,如下所示:
CM_Get_Device_Interface_Property
或带有DEVPKEY_Device_InstanceId
的SetupDiGetDeviceInterfaceProperty
获取设备实例id (一个设备可以有多个接口)。CM_Get_DevNode_Property
或SetupDiGetDeviceProperty
和DEVPKEY_NAME
来获取设备的本地化友好名称(显示在设备管理器中)。以下是来自my test repo的通过CM_*
API编写的示例代码
bool FillDeviceInfo(const std::wstring& deviceInterfaceName)
{
// you need to provide deviceInterfaceName
// example from my system: `\\?\HID#VID_203A&PID_FFFC&MI_01#7&2de99099&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}`
DEVPROPTYPE propertyType;
ULONG propertySize = 0;
CONFIGRET cr = ::CM_Get_Device_Interface_PropertyW(deviceInterfaceName.c_str(), &DEVPKEY_Device_InstanceId, &propertyType, nullptr, &propertySize, 0);
if (cr != CR_BUFFER_SMALL)
return false;
std::wstring deviceId;
deviceId.resize(propertySize);
cr = ::CM_Get_Device_Interface_PropertyW(deviceInterfaceName.c_str(), &DEVPKEY_Device_InstanceId, &propertyType, (PBYTE)deviceId.data(), &propertySize, 0);
if (cr != CR_SUCCESS)
return false;
// here is deviceId will contain device instance id
// example from my system: `HID\VID_203A&PID_FFFC&MI_01\7&2de99099&0&0000`
DEVINST devInst;
cr = ::CM_Locate_DevNodeW(&devInst, (DEVINSTID_W)deviceId.c_str(), CM_LOCATE_DEVNODE_NORMAL);
if (cr != CR_SUCCESS)
return false;
propertySize = 0;
cr = ::CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_NAME, &propertyType, nullptr, &propertySize, 0);
if (cr != CR_BUFFER_SMALL)
return false;
std::wstring friendlyString;
friendlyString.resize(propertySize);
cr = ::CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_NAME, &propertyType, (PBYTE)friendlyString.data(), &propertySize, 0);
// here is friendlyString will contain localized device friendly name
propertySize = 0;
cr = ::CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_Device_Manufacturer, &propertyType, nullptr, &propertySize, 0);
if (cr != CR_BUFFER_SMALL)
return false;
std::wstring manufacturer;
manufacturer.resize(propertySize);
cr = ::CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_Device_Manufacturer, &propertyType, (PBYTE)manufacturer.data(), &propertySize, 0);
// here is manufacturer will contain localized device "manufacturer-identifier"
return true;
}
更新:事实证明,HidD_GetProductString
和家族正在为HID键盘和鼠标工作。您只需以只读方式打开它的设备接口(路径)。请参见https://github.com/DJm00n/RawInputDemo/blob/master/RawInputLib/RawInputDevice.cpp#L77-L86示例。
https://stackoverflow.com/questions/12656236
复制相似问题