返回

Citrix环境下解决HidD_GetPhysicalDescriptor GetLastError 87错误:全方位指南

windows

在Citrix虚拟化环境中,不少开发者在使用USB重定向连接HID设备时,会遇到HidD_GetPhysicalDescriptor函数返回GetLastError 87错误的情况。这个问题在本地直接连接设备时通常不会出现,这让很多开发者感到困惑。我们先来深入了解一下这个问题的根源。

Citrix环境下,USB设备的连接方式与本地连接有所不同。Citrix使用了一种称为USB重定向的技术,将用户的USB设备虚拟化后呈现给虚拟桌面。这种机制虽然方便了用户在虚拟环境中使用USB设备,但也带来了一些潜在问题。其中之一就是USB数据传输的延迟和中断。

当我们调用HidD_GetPhysicalDescriptor函数获取HID设备的物理符时,函数需要与设备进行通信,并等待设备返回数据。在Citrix环境中,由于USB重定向机制的存在,这个通信过程可能会受到延迟或中断的影响。如果函数在设定的时间内没有收到设备的响应,就会返回GetLastError 87错误,提示操作超时。

那么,我们该如何解决这个问题呢?

首先,我们可以尝试增加HidD_GetPhysicalDescriptor函数的超时时间。HidD_GetPhysicalDescriptor函数默认的超时时间可能不足以应对Citrix环境下的延迟。我们可以通过调用HidD_SetHidCollectionParameters函数,并设置HidP_GetPhysicalDescriptorTimeout参数来增加超时时间。例如,我们可以将超时时间设置为5秒:

HidP_GetPhysicalDescriptorTimeout timeout = { 5000 }; // 5秒
HidD_SetHidCollectionParameters(hDev, NULL, &timeout);

如果增加超时时间仍然无法解决问题,我们可以考虑使用GetDeviceRegistryProperty函数来获取设备的物理符。GetDeviceRegistryProperty函数可以从设备的注册表属性中读取设备信息,包括物理描述符。这种方法绕过了直接与设备通信的过程,因此可以避免USB重定向带来的延迟和中断问题。

DWORD dwSize = 0;
HidD_GetDeviceRegistryProperty(hDev, HID_PROPERTY_PHYSICAL_DESCRIPTOR, &dwSize, NULL, 0);

PUCHAR pu8DataBuf = new UCHAR[dwSize];
if (HidD_GetDeviceRegistryProperty(hDev, HID_PROPERTY_PHYSICAL_DESCRIPTOR, &dwSize, pu8DataBuf, dwSize)) {
  // 成功获取物理描述符
}

当然,我们也需要考虑Citrix驱动程序本身的问题。过旧或不兼容的Citrix USB重定向驱动程序可能会导致与HID设备的通信问题。因此,确保Citrix驱动程序更新到最新版本也是解决问题的一个重要步骤。

此外,我们还需要排除一些基本的硬件问题。检查USB连接的稳定性,确保线缆牢固连接,并且没有其他设备占用相同的USB端口。这些看似简单的检查步骤,往往能帮助我们快速解决问题。

最后,如果以上方法都无法解决问题,我们还可以考虑使用其他API来获取设备的物理描述符。例如,SetupDiGetDeviceProperty函数也可以用来获取设备的各种属性信息,包括物理描述符。

在实际应用中,我们可以根据具体情况选择合适的解决方案。例如,如果我们知道某个HID设备在Citrix环境下通信延迟较大,我们可以直接将HidD_GetPhysicalDescriptor函数的超时时间设置为一个较大的值。如果我们希望代码具有更好的兼容性,可以使用GetDeviceRegistryProperty函数或SetupDiGetDeviceProperty函数来获取设备信息。

常见问题解答

  1. 为什么HidD_GetPhysicalDescriptor函数在Citrix环境下容易返回GetLastError 87错误?

    Citrix的USB重定向机制会引入额外的延迟和中断,导致HidD_GetPhysicalDescriptor函数无法在默认超时时间内获取设备的物理描述符。

  2. 增加HidD_GetPhysicalDescriptor函数的超时时间是否一定能解决问题?

    不一定。增加超时时间可以提高函数获取描述符的成功率,但如果Citrix环境下的延迟非常严重,或者设备本身存在问题,即使增加超时时间也可能无法解决问题。

  3. GetDeviceRegistryProperty函数和SetupDiGetDeviceProperty函数有什么区别?

    GetDeviceRegistryProperty函数专门用于获取HID设备的属性信息,而SetupDiGetDeviceProperty函数则可以获取各种设备的属性信息。在获取HID设备的物理描述符时,GetDeviceRegistryProperty函数更加便捷。

  4. 如何确定Citrix USB重定向驱动程序是否为最新版本?

    可以通过Citrix官方网站或Citrix XenApp/XenDesktop管理控制台查看当前安装的驱动程序版本,并与官方最新版本进行比较。

  5. 如果以上方法都无法解决问题,我该怎么办?

    可以尝试联系Citrix技术支持,或者咨询HID设备的厂商,寻求更专业的帮助。