VB6的,还得多测,不是我写的 Option Explicit Dim boTimeOut As BooleanPrivate Const DRIVE_CDROM As Long = 5 Private Const DRIVE_REMOVABLE As Long = 2Private Const GENERIC_READ As Long = &H80000000 Private Const GENERIC_WRITE As Long = &H40000000Private Const OPEN_EXISTING As Long = 3 Private Const FILE_DEVICE_FILE_SYSTEM As Long = 9 Private Const FILE_DEVICE_MASS_STORAGE As Long = &H2D& Private Const METHOD_BUFFERED As Long = 0 Private Const FILE_ANY_ACCESS As Long = 0 Private Const FILE_READ_ACCESS As Long = 1 Private Const LOCK_VOLUME As Long = 6 Private Const DISMOUNT_VOLUME As Long = 8 Private Const EJECT_MEDIA As Long = &H202 Private Const MEDIA_REMOVAL As Long = &H201 Private Const INVALID_HANDLE_VALUE As Long = -1Private Const LOCK_TIMEOUT As Long = 1000 Private Const LOCK_RETRIES As Long = 20Private Declare Function GetDriveType Lib "kernel32.dll" _ Alias "GetDriveTypeA" _ (ByVal nDrive As String) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" _ (ByVal hObject As Long) As LongPrivate Declare Function CreateFile Lib "kernel32.dll" Alias "CreateFileA" _ (ByVal lpFileName As String, _ ByVal dwDesiredAccess As Long, _ ByVal dwShareMode As Long, _ ByRef lpSecurityAttributes As Long, _ ByVal dwCreationDisposition As Long, _ ByVal dwFlagsAndAttributes As Long, _ ByVal hTemplateFile As Long) As Long
Private Declare Function DeviceIoControl Lib "kernel32.dll" _ (ByVal hDevice As Long, _ ByRef dwIoControlCode As Long, _ ByRef lpInBuffer As Any, _ ByVal nInBufferSize As Long, _ ByRef lpOutBuffer As Any, _ ByVal nOutBufferSize As Long, _ ByRef lpBytesReturned As Long, _ ByRef lpOverlapped As Long) As Long Private Function CTL_CODE(lngDevFileSys As Long, lngFunction As Long, _ lngMethod As Long, lngAccess As Long) As Long CTL_CODE = (lngDevFileSys * (2 ^ 16)) Or (lngAccess * (2 ^ 14)) Or (lngFunction * (2 ^ 2)) Or lngMethod End FunctionPrivate Function OpenVolume(strLetter As String, lngVolHandle As Long) As Boolean Dim lngDriveType As Long Dim lngAccessFlags As Long Dim strVolume As String lngDriveType = GetDriveType(strLetter) Select Case lngDriveType Case DRIVE_REMOVABLE lngAccessFlags = GENERIC_READ Or GENERIC_WRITE Case DRIVE_CDROM lngAccessFlags = GENERIC_READ Case Else OpenVolume = False Exit Function End Select strVolume = "\\.\" & strLetter lngVolHandle = CreateFile(strVolume, lngAccessFlags, 0, _ ByVal CLng(0), OPEN_EXISTING, ByVal CLng(0), ByVal CLng(0)) If lngVolHandle = INVALID_HANDLE_VALUE Then OpenVolume = False Exit Function End If OpenVolume = True End FunctionPrivate Function CloseVolume(lngVolHandle As Long) As Boolean Dim lngReturn As Long lngReturn = CloseHandle(lngVolHandle) If lngReturn = 0 Then CloseVolume = False Else CloseVolume = True End If End FunctionPrivate Function LockVolume(ByRef lngVolHandle As Long) As Boolean Dim lngBytesReturned As Long Dim intCount As Integer Dim intI As Integer Dim boLocked As Boolean Dim lngFunction As Long lngFunction = CTL_CODE(FILE_DEVICE_FILE_SYSTEM, LOCK_VOLUME, METHOD_BUFFERED, FILE_ANY_ACCESS) intCount = LOCK_TIMEOUT / LOCK_RETRIES boLocked = False For intI = 0 To LOCK_RETRIES boTimeOut = False Timer1.Interval = intCount Timer1.Enabled = True Do Until boTimeOut = True Or boLocked = True boLocked = DeviceIoControl(lngVolHandle, ByVal lngFunction, _ CLng(0), 0, CLng(0), 0, lngBytesReturned, ByVal CLng(0)) DoEvents Loop If boLocked = True Then LockVolume = True Timer1.Enabled = False Exit Function End If Next intI LockVolume = False End Function Private Function DismountVolume(lngVolHandle As Long) As Boolean Dim lngBytesReturned As Long Dim lngFunction As Long lngFunction = CTL_CODE(FILE_DEVICE_FILE_SYSTEM, DISMOUNT_VOLUME, METHOD_BUFFERED, FILE_ANY_ACCESS) DismountVolume = DeviceIoControl(lngVolHandle, ByVal lngFunction, _ 0, 0, 0, 0, lngBytesReturned, ByVal 0) End Function Private Function PreventRemovalofVolume(lngVolHandle As Long) As Boolean Dim boPreventRemoval As Boolean Dim lngBytesReturned As Long Dim lngFunction As Long boPreventRemoval = False lngFunction = CTL_CODE(FILE_DEVICE_MASS_STORAGE, MEDIA_REMOVAL, METHOD_BUFFERED, FILE_READ_ACCESS) PreventRemovalofVolume = DeviceIoControl(lngVolHandle, ByVal lngFunction, _ boPreventRemoval, Len(boPreventRemoval), 0, 0, lngBytesReturned, ByVal 0) End Function Private Function AutoEjectVolume(lngVolHandle As Long) As Boolean Dim lngFunction As Long Dim lngBytesReturned As Long lngFunction = CTL_CODE(FILE_DEVICE_MASS_STORAGE, EJECT_MEDIA, METHOD_BUFFERED, FILE_READ_ACCESS) AutoEjectVolume = DeviceIoControl(lngVolHandle, ByVal lngFunction, _ 0, 0, 0, 0, lngBytesReturned, ByVal 0) End FunctionPrivate Sub Eject(strVol As String) Dim lngVolHand As Long Dim boResult As Boolean Dim boSafe As Boolean strVol = strVol & ":" ' ' Open and get a Handle for the Volume ' boResult = OpenVolume(strVol, lngVolHand) If boResult = False Then MsgBox "Error Opening Volume " & Err.LastDllError Exit Sub End If ' ' Lock the Volume ' boResult = LockVolume(lngVolHand) If boResult = False Then MsgBox "Error Dismounting Volume " & Err.LastDllError CloseVolume (lngVolHand) Exit Sub End If ' 'Dismount the Volume ' boResult = DismountVolume(lngVolHand) If boResult = False Then MsgBox "Error Dismounting Volume " & Err.LastDllError CloseVolume (lngVolHand) Exit Sub End If ' ' Set to allow the Volume to be Removed ' boResult = PreventRemovalofVolume(lngVolHand) If boResult = False Then MsgBox "Error Allowing Removal of Volume " & Err.LastDllError CloseVolume (lngVolHand) Exit Sub End If boSafe = True ' ' Eject the Volume ' boResult = AutoEjectVolume(lngVolHand) If boSafe = True Then MsgBox "Media may be Safely Removed from Drive " & UCase(strVol) End If ' ' Close the Handle ' boResult = CloseVolume(lngVolHand) If boResult = False Then MsgBox "Error Closing Volume " & Err.LastDllError Exit Sub End If Unload Me End SubPrivate Sub Timer1_Timer() boTimeOut = True End Sub 'usage: Call Eject(drive letter without the colon)
好像是 xxx /remove
我看看去
devcon remove
拔除usb裝置
devcon disable
要不剩下的发不上来了
http://support.microsoft.com/?kbid=311272DevCon 是一个带有内置文档的命令行实用工具。如果您运行 devcon help 命令,将会出现以下命令列表和描述信息。devcon help 命令可提供关于任何命令的详细帮助。使用其中的某些命令,您可以指定远程目标计算机。如果您在 WOW64 上使用 32 位版的 DevCon,则以下命令有效。设备控制台帮助:
devcon.exe [-r] [-m:\\<machine>] <command> [<arg>...]
-r 如果指定它,在命令完成后若需要则重新启动计算机。
<machine> 是目标计算机的名称。
<command> 是将要执行的命令(如下所示)。
<arg>... 是命令需要的一个或多个参数。
要获取关于某一特定命令的帮助,请键入:devcon.exe help <command>
classfilter 允许修改类别筛选程序。
classes 列出所有设备安装类别。
disable 禁用与指定的硬件或实例 ID 匹配的设备。
driverfiles 列出针对设备安装的驱动程序文件。
drivernodes 列出设备的所有驱动程序节点。
enable 启用与指定的硬件或实例 ID 匹配的设备。
find 查找与指定的硬件或实例 ID 匹配的设备。
findall 查找设备,包括那些未显示的设备。
help 显示此信息。
hwids 列出设备的硬件 ID。
install 手动安装设备。
listclass 列出某一安装类别的所有设备。
reboot 重新启动本地计算机。
remove 删除与特定的硬件或实例 ID 匹配的设备。
rescan 扫描以发现新的硬件。
resources 列出设备的硬件资源。
restart 重新启动与特定的硬件或实例 ID 匹配的设备。
stack 列出预期的设备驱动程序堆栈。
status 列出设备的运行状态。
update 手动更新设备。
UpdateNI 手动更新设备,无用户提示
SetHwID 添加、删除和更改根枚举设备的硬件 ID 的顺序。
119591 (http://support.microsoft.com/kb/119591/) 如何从联机服务获取 Microsoft 支持文件
Microsoft 已对此文件进行了病毒扫描。Microsoft 使用的是该文件发布时可以获得的最新病毒检测软件。该文件存储在安全性得到增强的服务器上,以防止在未经授权的情况下对其进行更改。 DevCon.exe 文件包含以下文件:
文件 说明
I386\DevCon.exe 32 位 DevCon 工具的二进制文件。此文件在 64 位 Windows 上不能充分发挥作用。
Ia64\DevCon.exe 64 位 DevCon 工具的二进制文件。 注意:DevCon 的源代码也可以从 Windows DDK(位于 http://www.microsoft.com/whdc/devtools/ddk/default.mspx/ (http://www.microsoft.com/whdc/devtools/ddk/default.mspx/))中得到,路径是 DDK root\Src\Setup\Devcon,此位置还提供了文档。
http://support.microsoft.com/default.aspx?scid=kb;en-us;165721
Option Explicit
Dim boTimeOut As BooleanPrivate Const DRIVE_CDROM As Long = 5
Private Const DRIVE_REMOVABLE As Long = 2Private Const GENERIC_READ As Long = &H80000000
Private Const GENERIC_WRITE As Long = &H40000000Private Const OPEN_EXISTING As Long = 3
Private Const FILE_DEVICE_FILE_SYSTEM As Long = 9
Private Const FILE_DEVICE_MASS_STORAGE As Long = &H2D&
Private Const METHOD_BUFFERED As Long = 0
Private Const FILE_ANY_ACCESS As Long = 0
Private Const FILE_READ_ACCESS As Long = 1
Private Const LOCK_VOLUME As Long = 6
Private Const DISMOUNT_VOLUME As Long = 8
Private Const EJECT_MEDIA As Long = &H202
Private Const MEDIA_REMOVAL As Long = &H201
Private Const INVALID_HANDLE_VALUE As Long = -1Private Const LOCK_TIMEOUT As Long = 1000
Private Const LOCK_RETRIES As Long = 20Private Declare Function GetDriveType Lib "kernel32.dll" _
Alias "GetDriveTypeA" _
(ByVal nDrive As String) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" _
(ByVal hObject As Long) As LongPrivate Declare Function CreateFile Lib "kernel32.dll" Alias "CreateFileA" _
(ByVal lpFileName As String, _
ByVal dwDesiredAccess As Long, _
ByVal dwShareMode As Long, _
ByRef lpSecurityAttributes As Long, _
ByVal dwCreationDisposition As Long, _
ByVal dwFlagsAndAttributes As Long, _
ByVal hTemplateFile As Long) As Long
Private Declare Function DeviceIoControl Lib "kernel32.dll" _
(ByVal hDevice As Long, _
ByRef dwIoControlCode As Long, _
ByRef lpInBuffer As Any, _
ByVal nInBufferSize As Long, _
ByRef lpOutBuffer As Any, _
ByVal nOutBufferSize As Long, _
ByRef lpBytesReturned As Long, _
ByRef lpOverlapped As Long) As Long
Private Function CTL_CODE(lngDevFileSys As Long, lngFunction As Long, _
lngMethod As Long, lngAccess As Long) As Long
CTL_CODE = (lngDevFileSys * (2 ^ 16)) Or (lngAccess * (2 ^ 14)) Or (lngFunction * (2 ^ 2)) Or lngMethod
End FunctionPrivate Function OpenVolume(strLetter As String, lngVolHandle As Long) As Boolean
Dim lngDriveType As Long
Dim lngAccessFlags As Long
Dim strVolume As String
lngDriveType = GetDriveType(strLetter)
Select Case lngDriveType
Case DRIVE_REMOVABLE
lngAccessFlags = GENERIC_READ Or GENERIC_WRITE
Case DRIVE_CDROM
lngAccessFlags = GENERIC_READ
Case Else
OpenVolume = False
Exit Function
End Select
strVolume = "\\.\" & strLetter
lngVolHandle = CreateFile(strVolume, lngAccessFlags, 0, _
ByVal CLng(0), OPEN_EXISTING, ByVal CLng(0), ByVal CLng(0))
If lngVolHandle = INVALID_HANDLE_VALUE Then
OpenVolume = False
Exit Function
End If
OpenVolume = True
End FunctionPrivate Function CloseVolume(lngVolHandle As Long) As Boolean
Dim lngReturn As Long
lngReturn = CloseHandle(lngVolHandle)
If lngReturn = 0 Then
CloseVolume = False
Else
CloseVolume = True
End If
End FunctionPrivate Function LockVolume(ByRef lngVolHandle As Long) As Boolean
Dim lngBytesReturned As Long
Dim intCount As Integer
Dim intI As Integer
Dim boLocked As Boolean
Dim lngFunction As Long
lngFunction = CTL_CODE(FILE_DEVICE_FILE_SYSTEM, LOCK_VOLUME, METHOD_BUFFERED, FILE_ANY_ACCESS)
intCount = LOCK_TIMEOUT / LOCK_RETRIES
boLocked = False
For intI = 0 To LOCK_RETRIES
boTimeOut = False
Timer1.Interval = intCount
Timer1.Enabled = True
Do Until boTimeOut = True Or boLocked = True
boLocked = DeviceIoControl(lngVolHandle, ByVal lngFunction, _
CLng(0), 0, CLng(0), 0, lngBytesReturned, ByVal CLng(0))
DoEvents
Loop
If boLocked = True Then
LockVolume = True
Timer1.Enabled = False
Exit Function
End If
Next intI
LockVolume = False
End Function
Private Function DismountVolume(lngVolHandle As Long) As Boolean
Dim lngBytesReturned As Long
Dim lngFunction As Long
lngFunction = CTL_CODE(FILE_DEVICE_FILE_SYSTEM, DISMOUNT_VOLUME, METHOD_BUFFERED, FILE_ANY_ACCESS)
DismountVolume = DeviceIoControl(lngVolHandle, ByVal lngFunction, _
0, 0, 0, 0, lngBytesReturned, ByVal 0)
End Function
Private Function PreventRemovalofVolume(lngVolHandle As Long) As Boolean
Dim boPreventRemoval As Boolean
Dim lngBytesReturned As Long
Dim lngFunction As Long
boPreventRemoval = False
lngFunction = CTL_CODE(FILE_DEVICE_MASS_STORAGE, MEDIA_REMOVAL, METHOD_BUFFERED, FILE_READ_ACCESS)
PreventRemovalofVolume = DeviceIoControl(lngVolHandle, ByVal lngFunction, _
boPreventRemoval, Len(boPreventRemoval), 0, 0, lngBytesReturned, ByVal 0)
End Function
Private Function AutoEjectVolume(lngVolHandle As Long) As Boolean
Dim lngFunction As Long
Dim lngBytesReturned As Long
lngFunction = CTL_CODE(FILE_DEVICE_MASS_STORAGE, EJECT_MEDIA, METHOD_BUFFERED, FILE_READ_ACCESS)
AutoEjectVolume = DeviceIoControl(lngVolHandle, ByVal lngFunction, _
0, 0, 0, 0, lngBytesReturned, ByVal 0)
End FunctionPrivate Sub Eject(strVol As String)
Dim lngVolHand As Long
Dim boResult As Boolean
Dim boSafe As Boolean
strVol = strVol & ":"
'
' Open and get a Handle for the Volume
'
boResult = OpenVolume(strVol, lngVolHand)
If boResult = False Then
MsgBox "Error Opening Volume " & Err.LastDllError
Exit Sub
End If
'
' Lock the Volume
'
boResult = LockVolume(lngVolHand)
If boResult = False Then
MsgBox "Error Dismounting Volume " & Err.LastDllError
CloseVolume (lngVolHand)
Exit Sub
End If
'
'Dismount the Volume
'
boResult = DismountVolume(lngVolHand)
If boResult = False Then
MsgBox "Error Dismounting Volume " & Err.LastDllError
CloseVolume (lngVolHand)
Exit Sub
End If
'
' Set to allow the Volume to be Removed
'
boResult = PreventRemovalofVolume(lngVolHand)
If boResult = False Then
MsgBox "Error Allowing Removal of Volume " & Err.LastDllError
CloseVolume (lngVolHand)
Exit Sub
End If
boSafe = True
'
' Eject the Volume
'
boResult = AutoEjectVolume(lngVolHand)
If boSafe = True Then
MsgBox "Media may be Safely Removed from Drive " & UCase(strVol)
End If
'
' Close the Handle
'
boResult = CloseVolume(lngVolHand)
If boResult = False Then
MsgBox "Error Closing Volume " & Err.LastDllError
Exit Sub
End If
Unload Me
End SubPrivate Sub Timer1_Timer()
boTimeOut = True
End Sub
'usage:
Call Eject(drive letter without the colon)
试下看
注意,devcon 是替代设备管理器的。已经知道有三个解决方案:
1 采用 hotplug.dll 动态库的 API 函数 "HotPlugEjectDevice",但此函数未公开,未知调用方法。2 Shell "RUNDLL32.EXE shell32.dll,Control_RunDLL hotplug.dll" 调出“拔下或弹出硬件”窗口,SendMessage 或 Sendkeys 模拟手工移除。3 用楼上的 DeviceIoControl 来处理。研究中。
Shell "RUNDLL32.EXE shell32.dll,Control_RunDLL hotplug.dll"
以及
SendKeys缺点是屏上闪一下。以后再研究直接用 API。