简体   繁体   English

如何以编程方式拔出并重新插入任意USB设备?

[英]How to programmatically unplug & replug an arbitrary USB device?

I'm trying to fix a non-responsive USB device that's masquerading as a virtual COM port. 我正在尝试修复伪装成虚拟COM端口的无响应USB设备。 Manual replugging works, but there may be up to 12 of these units. 手动重新插入可以工作,但其中最多可以包含12个。 Is there an API command to do the programmatic equivalent of the unplug/replug cycle? 是否有API命令可以执行与拔出/重新插入周期等效的编程?

What about using Devcon.exe to "remove" and then "rescan"? 使用Devcon.exe“删除”然后“重新扫描”怎么办?

DR 博士

You can use the C# Hardware Helper Lib and add the ResetDevice function . 您可以使用C#硬件帮助程序库并添加ResetDevice函数

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

Unfortunately, there isn't one that I know of. 不幸的是,我没有一个知道。 Physically unplugging the USB connection does specific electronic things with pullup resistors, such that the device knows it's unplugged. 物理上拔下USB连接会通过上拉电阻执行特定的电子操作,从而使设备知道已拔下。 I haven't encountered a host that attempts to be able to simulate this condition without physical unplugging. 我还没有遇到一个试图在不物理拔出的情况下模拟这种情况的主机。

Thought: under Device Manager, you can right-click your computer icon (top of the device tree) and "scan for changes". 想法:在“设备管理器”下,您可以右键单击计算机图标(在设备树顶部),然后“扫描更改”。 I'm not 100% sure, but I think if you "eject" a USB device (software "unplug" equivalent), then Scan for Hardware Changes, it will show back up even though it never actually left the port. 我不确定100%,但是我认为,如果您“弹出” USB设备(等效于软件“拔出”),然后扫描“查找硬件更改”,即使它从未真正离开端口,它也会备份显示。

If I'm right about that, you might be able to use the Microsoft.Win32.Shell class to emulate opening Control Panel --> Administrative Tools --> Device Manager and running the context-menu item. 如果我对此表示正确,则可以使用Microsoft.Win32.Shell类来模拟打开控制面板->管理工具->设备管理器并运行上下文菜单项。 It's worth a shot, anyway. 无论如何,值得一试。

Here's some hands on guidance: 以下是一些指导性的指导:

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

This is more hardcore: 这是更顽固的:

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

I'd say that using devcon.exe may solve some problems, not mine though. 我会说使用devcon.exe可能会解决一些问题,但不是我的。 Suppose that you can build a box with arrays of USB-ports, where the power line is interrupted with FETs controlled by a MCU. 假设您可以构建一个带有USB端口阵列的盒子,其中电源线被MCU控制的FET中断。 The MCU should talk something basic and reliable, like RS-232. MCU应该说一些基本而可靠的内容,例如RS-232。 There might be an arduino board that simplifies the scary hardware work. 可能会有一个arduino板简化了可怕的硬件工作。

As Greg Hewgill said, I don't think that it's possible. 正如格雷格·休吉尔(Greg Hewgill)所说,我认为这是不可能的。

Initiation of the whole usb startup is triggered by the usb slave (in your case your device). 整个USB启动的启动是由USB从设备(在您的情况下为设备)触发的。 The usb host (the pc) can send a message to the device to tell it to shut down, but once it's done that it's up to the device to start back up again. USB主机(PC)可以向设备发送一条消息,告诉它关闭,但是一旦完成,就由设备重新启动。 The host can't force it to. 主机不能强迫它。

To make matters worse you'll quite possibly find that the usb device is detecting the plug being inserted (by detecting the usb voltage on the power lines) to start up. 更糟糕的是,您很可能会发现USB设备正在检测正在插入的插头(通过检测电源线上的USB电压)以启动。 This is particularly true of bus powered devices. 对于总线供电的设备尤其如此。


It sounds like there are differences from your situation and the case of trying to unmount/remount usb drives. 听起来您的情况和尝试卸下/重新安装USB驱动器的情况有所不同。 When the usb drive is unmounted there is no reason that it can't stay enumerated on the pc. 卸载USB驱动器后,没有理由无法在PC上枚举它。 You're not actually reseting the usb drive, just making it's filesystem inactive. 您实际上并没有重置USB驱动器,只是使它的文件系统处于非活动状态。

I've looked at this for automated tests. 我已经将其用于自动化测试。 The best solution we came up with seems to be the ability of USB hubs to disconnect devices when they draw too much power. 我们想出的最好的解决方案似乎是USB集线器能够在设备消耗过多功率时断开它们的连接。 From a USB pserspective, it appears the USB host may instruct a hub to do so. 从USB角度来看,似乎USB主机可能指示集线器这样做。 With 12 devices, you will have hubs, so I'd suggest to investigate that path. 使用12台设备,您将拥有集线器,因此建议您调查该路径。

I had to do this for my car computer project a while back. 前一段时间,我不得不为我的车载计算机项目执行此操作。 The touchscreen drivers didn't like going into hibernate and needed to be replugged when the computer came back from hibernate. 触摸屏驱动程序不喜欢进入休眠状态,因此当计算机从休眠状态恢复时,需要重新插入触摸屏驱动程序。 The way I ended up solving it was to use Devcon.exe like DigitalRacer suggested. 我最终解决它的方法是使用DigitalRacer建议的Devcon.exe。 The trick however, was that remove/rescan on the controller didn't work. 但是,窍门是在控制器上执行删除/重新扫描操作无效。 I had to do the remove/rescan on a HUB upstream from the device (which subsequently disconnected all attached devices). 我必须在设备上游的HUB上执行删除/重新扫描(随后断开所有连接的设备的连接)。

If you have more than one of these on any particular host machine, you might save some time/frustration by plugging them into their own dedicated USB hub out from the machine - at least it's only one cable to unplug/plug to restart a couple of devices at a time. 如果您在任何特定主机上都具有多个端口,则可以将它们插入计算机专用的USB集线器中,从而节省一些时间/烦恼-至少只有一根电缆可以拔出/重新启动,以便重新启动一次设备。

You've probably thought of that, of course. 当然,您可能已经想到了。 :-) :-)

我们使用来可编程断开USB设备的连接。

The device itself may be able to do this (ie, perform a USB disconnect/reconnect sequence). 设备本身可以执行此操作(即执行USB断开/重新连接顺序)。

Have you contacted the device manufacturer, or if you are the manufacturer, the EE's that designed it? 您是否已联系设备制造商,或者如果您是制造商,请联系设计它的EE?

I had to do this when I designed a USB embedded device - programming could be accomplished through USB, but the device had to be able to disconnect and reconnect at several points to complete the process. 在设计USB嵌入式设备时,我必须这样做-可以通过USB完成编程,但是该设备必须能够断开并重新连接好几个点才能完成该过程。

Beyond that there's the brute force method of disabling the USB host device in device manager (I assume this can be done in software) and then re-enabling it. 除此之外,还有一种蛮力方法,即在设备管理器中禁用USB主机设备(我认为这可以在软件中完成),然后重新启用它。

If nothing else, Phidget has USB controlled relay boards which you can use to connect power or the USB lines themselves to hubs or individual devices. 如果没有其他问题,Phidg​​et拥有USB控制的中继板,您可以使用它们将电源或USB线本身连接到集线器或单个设备。

-Adam -亚当

可以通过编程方式卸载USB驱动器 ,但是,我不知道是否可以通过代码完成卸载

In Eject USB disks using C# ( The Code Project ) look for this: 使用C#代码项目弹出USB磁盘中,查找以下内容:

CM_Request_Device_Eject function CM_Request_Device_Eject函数

This is the SetupApi function that ejects a device (any device that can be ejected). 这是用来弹出设备(可以弹出的任何设备)的SetupApi函数。 It takes a device instance handle (or devInst) as input... 它以设备实例句柄(或devInst)作为输入...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM