如何以编程方式拔掉& amp;重新插入任意USB设备?

时间:2008-09-26 09:07:16

标签: c++ winapi usb usbserial

我正在尝试修复伪装成虚拟COM端口的无响应USB设备。手动重新插入工作,但最多可能有12个这样的单位。是否有一个API命令来执行unplug / replug循环的程序化等效操作?

13 个答案:

答案 0 :(得分:9)

如何使用Devcon.exe“删除”然后“重新扫描”?

DR

答案 1 :(得分:3)

不幸的是,我所知道的并不存在。物理上拔掉USB连接可以通过上拉电阻实现特定的电子设备,这样设备就可以知道它已被拔掉。我没有遇到过一个试图能够在没有物理拔出的情况下模拟这种情况的主机。

答案 2 :(得分:3)

您可以使用C# Hardware Helper Lib并添加ResetDevice function

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;  
}  

答案 3 :(得分:2)

思想:在设备管理器下,您可以右键单击计算机图标(设备树顶部)和“扫描更改”。我不是百分百肯定,但我认为如果你“弹出”一个USB设备(软件“拔掉”等效物),然后扫描硬件更改,它会显示备份,即使它实际上从未离开过该端口。

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

答案 4 :(得分:1)

正如Greg Hewgill所说,我不认为这是可能的。

整个usb启动的启动由usb slave(在你的情况下是你的设备)触发。 USB主机(PC)可以向设备发送消息以告知它关闭,但一旦完成,由设备重新开始备份。主持人不能强迫它。

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


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

答案 5 :(得分:1)

我已经看过这个以进行自动化测试。我们提出的最佳解决方案似乎是USB集线器在耗电过多时断开设备的能力。从USB设备来看,USB主机似乎可以指示集线器这样做。使用12个设备,您将拥有集线器,因此我建议调查该路径。

答案 6 :(得分:1)

我不得不为我的汽车电脑项目做这件事。触摸屏驱动程序不喜欢进入休眠状态,当计算机从休眠状态恢复时需要重新插入。我最终解决它的方法是使用像DigitalRacer建议的Devcon.exe。但是,技巧是控制器上的删除/重新扫描不起作用。我不得不在设备上游的HUB上进行移除/重新扫描(随后断开所有连接的设备)。

答案 7 :(得分:1)

这里有一些指导:

http://digital.ni.com/public.nsf/allkb/1D120A90884C25AF862573A700602459

这是更多的核心:

http://support.microsoft.com/kb/311272

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

答案 8 :(得分:0)

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

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

答案 9 :(得分:0)

可以通过编程方式unmounting a USB drive完成,但我不知道是否可以通过代码重新安装。

答案 10 :(得分:0)

Eject USB disks using C# The Code Project)中寻找:

  

CM_Request_Device_Eject 功能

     

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

答案 11 :(得分:0)

我们使用this来编程断开usb设备。

答案 12 :(得分:0)

设备本身可以执行此操作(即执行USB断开/重新连接序列)。

您是否曾与设备制造商联系,或者如果您是制造商,则设计了EE?

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

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

如果不出意外,Phidg​​et有USB控制的继电器板,您可以使用它来将电源或USB线本身连接到集线器或单个设备。

- 亚当