How to programmatically unplug & replug an arbitrary USB device?

55,058

Solution 1

You can use the C# Hardware Helper Lib and add the 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;  
}  

Solution 2

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. I haven't encountered a host that attempts to be able to simulate this condition without physical unplugging.

Solution 3

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.

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. It's worth a shot, anyway.

Solution 4

As Greg Hewgill said, I don't think that it's possible.

Initiation of the whole usb startup is triggered by the usb slave (in your case your device). 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. 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. 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. When the usb drive is unmounted there is no reason that it can't stay enumerated on the pc. You're not actually reseting the usb drive, just making it's filesystem inactive.

Solution 5

Here's some hands on guidance:

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

This is more hardcore:

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

I'd say that using devcon.exe may solve some problems, not mine though. Suppose that you can build a box with arrays of USB-ports, where the power line is interrupted with FETs controlled by a MCU. The MCU should talk something basic and reliable, like RS-232. There might be an arduino board that simplifies the scary hardware work.

Share:
55,058
Admin
Author by

Admin

Updated on December 02, 2020

Comments

  • Admin
    Admin over 3 years

    I'm trying to fix a non-responsive USB device that's masquerading as a virtual COM port. Manual replugging works, but there may be up to 12 of these units. Is there an API command to do the programmatic equivalent of the unplug/replug cycle?

  • Andrew Edgecombe
    Andrew Edgecombe over 15 years
    Can a device that's "...masquerading as a virtual com port." be ejected?
  • Sergey Podobry
    Sergey Podobry over 8 years
    Unfortunately it works only if the device is not busy. Otherwise it asks for a reboot.
  • lahjaton_j
    lahjaton_j almost 8 years
    DISCLAIMER: It's not a programmatic solution.