gzh888666
发表于 2011-8-21 01:07:21
这个确实有点难度测试不成功
case
发表于 2011-8-21 01:21:20
我这里有个工具,是以前收集到的,这个工具可以实现LZ的想法
USB_Safely_Remove_4.2_CN.exe
haijie1223
发表于 2011-8-21 08:05:13
回复 17# case
楼主的意思是重新识别,不单单是弹出来这么简单,关键是还能不用插拔继续识别。
haijie1223
发表于 2011-8-21 08:06:38
因为弹出来这个功能相对简单些,但是想不用插拔再次识别的话,我觉得要是能控制把usb口断电,再通电或许会实现。
pusofalse
发表于 2011-8-21 08:53:27
已经安全弹出的U盘,它的设备错误号为47,表示已标记为“安全删除”但仍没有从系统中物理拔出。设备管理器中提示说“若要让这个设备重新工作,需拔出再重新插入”,其实也不必再次插拔,找到这个U盘的父设备,卸载这个父设备再重新更新一次驱动程序 就好了,U盘又能正常工作了。
#include <SetupAPI.au3>
Local $hDeviceInfoList, $tDeviceInfo, $hDevInst, $iStatus, $hParentDevInst, $hNewDeviceInfoList, $sDeviceID
$hDeviceInfoList = _SetupDiGetClassDevs($DIGCF_PRESENT, "DiskDrive")
For $i = 0 To 4096
If _SetupDiEnumDeviceInfo($hDeviceInfoList, $i, $tDeviceInfo) = 0 Then ExitLoop
$hDevInst = DllStructGetData($tDeviceInfo, "DevInst")
$iStatus = _CM_Get_DevNode_Status($hDevInst)
If (@extended <> 47) Then ContinueLoop
$hParentDevInst = _CM_Get_Parent($hDevInst)
$sDeviceID = _CM_Get_Device_ID($hParentDevInst)
$hNewDeviceInfoList = _SetupDiCreateDeviceInfoList()
_SetupDiOpenDeviceInfo($hNewDeviceInfoList, $sDeviceID, $tDeviceInfo)
_SetupDiRemoveDevice($hNewDeviceInfoList, $tDeviceInfo, 1)
_CM_Scan_Device_Changes("", $CM_REENUMERATE_RETRY_INSTALLATION)
_SetupDiDestroyDeviceInfoList($hDeviceInfoList)
_SetupDiDestroyDeviceInfoList($hNewDeviceInfoList)
Next
MsgBox(48, "OK", "Done.")
haijie1223
发表于 2011-8-21 11:20:57
回复 20# pusofalse
p版 我的系统是win7 我看过设备管理器确实是错误号47,不过运行上面代码没有效果。
gzh888666
发表于 2011-8-21 12:08:50
回复 20# pusofalse
win7下确实无法重新识别。我用P版安全删除U盘的UDF删除后测试这个没有效果!
case
发表于 2011-8-21 12:08:59
回复 18# haijie1223
我收集的这个工具可以在不插拔U盘的情况下重新识别,而且在无法退出U盘的情况下查看是哪个进程或文件导致USB无法弹出.
xyhqqaa
发表于 2011-8-21 12:35:49
回复 23# case
刚安装测试.发现,其实这工具的安全退出,当我打开U盘内的一个程序.然后停止U盘设备不关闭占用程序,程序依然存在没关闭.而且我发现,它提示是停止移动设备,而不是删除移动设备.所以我猜,它不是真的移除设备,而只是隐藏掉而已.但是它的查找占用程序功能不错
xyhqqaa
发表于 2011-8-21 12:38:53
回复 20# pusofalse
P大的东东/.俺新手还需要好好拜读下{:face (245):}..我先看看在查找您的一些帖子看看,看看能再学到些什么不
pusofalse
发表于 2011-8-21 12:41:09
20#的代码确实有BUG,修正了一下,代码过长,只贴部分,附件中包含全部代码,相当于是个函数库了(其实是打算重写SetupAPI.au3)。
Local $pDeviceInfo
Local $hDeviceInfoList = _DevMgr_EnumEjectedDevices("")
If ($hDeviceInfoList = 0) Or (@extended < 1) Then
MsgBox(48, "Error", "Error no devices have been safely removed.")
Exit
EndIf
For $i = 0 To @extended - 1
$pDeviceInfo = _DevMgr_EnumDeviceInfo($hDeviceInfoList, $i, $pDeviceInfo)
$hDevInst = _DevMgr_GetDevInstFromDeviceInfo($pDeviceInfo)
$sDisplayName = _DevMgr_GetDisplayName($hDevInst)
If MsgBox(52, $sDisplayName, "This device has been safely removed from your system, do you want to reload this device?") = 6 Then
_DevMgr_ReloadDevice($hDeviceInfoList, $pDeviceInfo, 0)
EndIf
Next
_DevMgr_ScanforHardwareChanges(0, 2)
MsgBox(48, "OK", "Done")
haijie1223
发表于 2011-8-21 13:37:19
回复 26# pusofalse
p版 依然没有效果
ps:问p版另一个问题:SetupAPI.au3中_SetupDiGetClassDevs($DIGCF_PRESENT, "display")其中的display是显卡,computer是计算机,那ide ata/atapi控制器的名字是什么?如图:请p版指点.
pusofalse
发表于 2011-8-21 15:00:07
本帖最后由 pusofalse 于 2011-8-21 15:05 编辑
回复 27# haijie1223
ide ata/atapi控制器 应该是hdc,更多详细的设备类名,调用_CM_Enumerate_Classes、_SetupDiClassNameFromGuid。
26#的代码,haijie1223兄测试输出结果是什么? 我在XP SP3中测试100%成功,用管理员权限运行试下。
arkhe
发表于 2011-8-21 15:03:12
回复pusofalse
win7下确实无法重新识别。我用P版安全删除U盘的UDF删除后测试这个没有效果!
gzh888666 发表于 2011-8-21 12:08 http://www.autoitx.com/images/common/back.gif
win7也可以的,工作中我们突破域锁定就是用的uninstall。
用au3自动实现的方法没试过...
haijie1223
发表于 2011-8-21 16:40:28
回复 28# pusofalse
谢谢p版的回复,在xp下已经测试,确实可以,不过win7下测试,直到最后的“done”消息窗口出现,也没有反应,U盘没有任何反应,也不会出现正装驱动的提示,xp下有的。