我正在编写一个C#小应用程序,在检测到另一个鼠标设备时禁用一个设备(我的笔记本触摸板),并在未检测到鼠标时再次启用触摸板。我甚至无法在设备管理器中禁用触摸板(它运行在默认的鼠标类驱动程序上)。
我正在进行设备驱动程序开发,所以我想也许我可以编写一个小的过滤器驱动程序,它只接受IOCTL来启用和禁用鼠标事件消息在设备堆栈上的传递,并通过原始PDO从用户模式获取消息。然而,I asked that question和其他人建议我可以通过SetupDi..函数在用户模式下完成此操作。这将非常好。因为这种原始PDO通信方法是一种需要使用的PITA。
我以前只使用过 SetupDiGetClassDevs,而且有这么多这样的东西,有没有对Win32 API的这一部分更有经验的人可以快速告诉我,我应该调用哪个来停止/禁用鼠标设备或其接口,或者在框架的黑暗角落里是否有什么东西可以做到这一点(也许在WMI中?)
**更新(24/9/09)**我想出了如何用过滤器驱动程序做到这一点,并在my original question上发布了我是如何做到的。我仍然想知道是否有可能直接从Win32启用或禁用设备,如果有,如何-所以我将把这个问题留在一边。
4条答案
按热度按时间0s0u357o1#
您可以使用SetupDi API从Win32启用/禁用设备(因此可以通过P/Invoke从C#启用/禁用),但并非所有设备都可以通过这种方式“禁用”。
您在尝试从Win32禁用触摸板时遇到的问题(或WMI或调用
SetupDi*
系列函数的任何其他API)是大多数带触摸板的笔记本电脑中的默认鼠标驱动程序(“PS/2兼容鼠标”)不支持使用SetupDi
API禁用。我怀疑这可能是因为使用PS/2连接器的实际旧鼠标无法“不要在不冲洗硬件的情况下进行热拆卸。要验证您是否无法禁用,请进入设备管理器并右键单击鼠标驱动程序。如果您看到禁用选项,您可以使用SetupDi来禁用它。如果没有禁用选项,您就不走运了...欢迎来到IOCTL世界!
如果您看到了禁用选项,那么下面的代码(从我找到的here的VB示例移植到C#)应该可以让您禁用和重新启用设备。
下面是调用该库的代码:
这是库本身,改编自here。
请注意,当您在
int index = GetIndexOfInstance(diSetHandle, diData, instanceId);
行上获得Index-Out-Of-Bounds异常时,您可能使用了错误的设备classGuid或错误的instanceId。另请注意,当您在64位Windows平台上运行此代码时,在生成应用程序时应将目标定位为64位平台。否则,即当应用程序作为32位进程在64位Windows平台上运行时,您将收到SetupAPI错误InWow 64(ERROR_IN_WOW64)。
当目标是64位Windows平台时,您可能还必须对应用程序的其他部分进行更改(例如,在执行指针运算时),以防止溢出。
n53p2ov02#
一种方法可能是使用Windows Management Instrumentation层,在这个层中似乎定义了一些与设备相关的类。
yyyllmsg3#
同样的情况也可以在这里找到:CM_Request_Device_EjectW和CM_Query_And_Remove_SubTreeW
neskvpey4#
如果您想 * 切换 * 设备启用状态,可以通过将
SetDeviceEnabled
替换为以下内容来修改@JustinGrant的惊人解决方案: