C++ 如何以编程方式拔出&;重新安装任意USB设备?

C++ 如何以编程方式拔出&;重新安装任意USB设备?,c++,winapi,usb,usbserial,C++,Winapi,Usb,Usbserial,我正在尝试修复伪装成虚拟COM端口的无响应USB设备。手动重新加注工作正常,但可能有多达12个这样的装置。是否有API命令来执行与拔掉/重新拔掉循环相当的编程操作?不幸的是,我所知道的没有。从物理上拔下USB连接会使用上拉电阻器执行特定的电子操作,这样设备就知道它已拔出。我没有遇到过一台主机试图在不进行物理拔出的情况下模拟这种情况。如果在任何特定主机上有多台这样的主机,您可以通过将它们从机器中插入自己的专用USB集线器来节省一些时间/挫折感-至少一次只需拔下/插入一根电缆即可重新启动两个设备 当

我正在尝试修复伪装成虚拟COM端口的无响应USB设备。手动重新加注工作正常,但可能有多达12个这样的装置。是否有API命令来执行与拔掉/重新拔掉循环相当的编程操作?

不幸的是,我所知道的没有。从物理上拔下USB连接会使用上拉电阻器执行特定的电子操作,这样设备就知道它已拔出。我没有遇到过一台主机试图在不进行物理拔出的情况下模拟这种情况。

如果在任何特定主机上有多台这样的主机,您可以通过将它们从机器中插入自己的专用USB集线器来节省一些时间/挫折感-至少一次只需拔下/插入一根电缆即可重新启动两个设备

当然,你可能已经想到了这一点。:-)

可以通过编程完成,但是,我不知道是否可以通过代码完成重新安装。

在()中查找:

CM_请求_设备_弹出功能

这是SetupApi函数 弹出设备(任何可以 被逐出)。它需要一个装置 实例句柄(或devInst)为 输入

如前所述,我认为这是不可能的

整个usb启动的启动由usb从设备(在您的情况下是您的设备)触发。usb主机(pc)可以向设备发送一条消息,告诉它关机,但一旦关机,设备就可以重新启动。主人不能强迫它

更糟糕的是,你很可能会发现usb设备正在检测插入的插头(通过检测电源线上的usb电压)以启动。总线供电设备尤其如此



听起来与您的情况以及尝试卸载/重新安装usb驱动器的情况有所不同。当usb驱动器卸载时,没有理由不能在pc上保持枚举状态。实际上,您并没有重置usb驱动器,只是使其文件系统处于非活动状态。

我已经查看了这个自动测试。我们提出的最佳解决方案似乎是USB集线器在设备耗电过大时能够断开设备的连接。从USB的角度来看,USB主机可能会指示集线器这样做。有了12台设备,您就有了集线器,所以我建议您研究一下这条路径。

我们过去常常通过编程断开usb设备。

思考:在设备管理器下,您可以右键单击计算机图标(设备树顶部)和“扫描更改”。我不是100%确定,但我认为如果你“弹出”一个USB设备(软件“拔出”等效),然后扫描硬件更改,它将显示备份,即使它从未真正离开端口


如果我说的没错,您可能可以使用Microsoft.Win32.Shell类模拟打开控制面板-->管理工具-->设备管理器并运行上下文菜单项。无论如何,这是值得一试的。

设备本身可能能够做到这一点(即,执行USB断开/重新连接序列)

您是否联系过设备制造商,或者如果您是制造商,是否联系过设计该设备的EE

当我设计一个USB嵌入式设备时,我必须这样做——编程可以通过USB完成,但设备必须能够在几个点断开和重新连接才能完成这个过程

除此之外,还有一种蛮力方法,即在设备管理器中禁用USB主机设备(我假设这可以在软件中完成),然后重新启用它

如果没有别的,Phidget有USB控制的中继板,您可以使用它将电源或USB线路本身连接到集线器或单个设备


-Adam

使用Devcon.exe“删除”然后“重新扫描”怎么样


DR

不久前,我不得不为我的汽车电脑项目做这个。触摸屏驱动程序不喜欢进入休眠状态,需要在计算机从休眠状态返回时重新启动。我最终解决这个问题的方法是像DigitalRacer建议的那样使用Devcon.exe。然而,诀窍在于控制器上的删除/重新扫描不起作用。我必须在设备上游的集线器上进行移除/重新扫描(随后断开所有连接的设备)

以下是一些实际操作指南:

这是更为核心的:

我想说使用devcon.exe可以解决一些问题,但不是我的问题。假设您可以构建一个带有USB端口阵列的盒子,其中电源线由MCU控制的FET中断。MCU应该讲一些基本且可靠的东西,比如RS-232。可能有一个arduino板可以简化可怕的硬件工作。

您可以使用并添加


“伪装成虚拟com端口”的设备能否被弹出?其次,devcon是Windows驱动程序工具包的一部分,也提供了源代码。需要管理员权限。可能重复的软件(如USB Safety Remove)可以通过重新启动整个USB集线器(包括其他连接的设备)来重新安装已拔出的USB设备。不幸的是,它仅在设备不忙时工作。否则它会要求重新启动。免责声明:这不是一个编程解决方案。
public bool ResetDevice( IntPtr hDevInfo, IntPtr devInfoData )  
// Need to add  
// public const int DICS_PROPCHANGE = ((0x00000003));   
// at the public class Native under //PARMS  
int szOfPcp;  
IntPtr ptrToPcp;  
int szDevInfoData;  
IntPtr ptrToDevInfoData;  

Native.SP_PROPCHANGE_PARAMS pcp = new Native.SP_PROPCHANGE_PARAMS();  
pcp.ClassInstallHeader.cbSize = Marshal.SizeOf(typeof(Native.SP_CLASSINSTALL_HEADER));  
pcp.ClassInstallHeader.InstallFunction = Native.DIF_PROPERTYCHANGE;  
pcp.StateChange = Native.DICS_PROPCHANGE; // for reset  
pcp.Scope = Native.DICS_FLAG_CONFIGSPECIFIC;  
pcp.HwProfile = 0;  

szOfPcp = Marshal.SizeOf(pcp);  
ptrToPcp = Marshal.AllocHGlobal(szOfPcp);  
Marshal.StructureToPtr(pcp, ptrToPcp, true);  
szDevInfoData = Marshal.SizeOf(devInfoData);  
ptrToDevInfoData = Marshal.AllocHGlobal(szDevInfoData);  
Marshal.StructureToPtr(devInfoData, ptrToDevInfoData, true);  

bool rslt1 = Native.SetupDiSetClassInstallParams(hDevInfo, ptrToDevInfoData, ptrToPcp,   Marshal.SizeOf(typeof(Native.SP_PROPCHANGE_PARAMS)));  
bool rstl2 = Native.SetupDiCallClassInstaller(Native.DIF_PROPERTYCHANGE, hDevInfo,   ptrToDevInfoData);  

if (rslt1 && rstl2)  
{  
    return true;  
}  
return false;  
}