以前也发过一几篇关于卸载USB设备的文章,其实原理都是一样都是使用同一个API "CM_Request_Device_Eject_ExW"来完成卸载工作,上一篇是通过遍历USB接点实现,这篇文章直接通过USB 的VID和PID获取其对应的DevInst来完成卸载工作。本篇文章通过使用了WMI技术来实现了很多关键点的功能。
查了很多资料想了很多方法也没找到从一个USB盘符获取该USB设备的VID和PID串比如,我的U盘VID和PID串是“Vid_0781&Pid_5151”,SerialNumber是“2204611D84C38930”,那么我们就可以通过
CM_Locate_DevNodeA(VarPtr(dwDevInst), "USB/Vid_0781&Pid_5151/2204611D84C38930", 0)来获取到dwDevInst,这样继续使用CM_Request_Device_Eject_ExA函数就可以完成对USB设备的卸载工作了。如果哪位朋友知道怎么从U盘的盘符获取到VID和PID串请与我联系,谢谢!
form
Option Explicit
Private Declare Function CM_Locate_DevNodeA Lib "setupapi.dll" (ByVal pdnDevInst As Long, ByVal DeviceInstanceId As String, ByVal ulFlags As Long) As Long
Private Declare Function CM_Request_Device_Eject_ExA Lib "setupapi.dll" (ByVal pdnDevInst As Long, ByVal VetoType As Long, ByVal pszVetoName As String, ByVal ulNameLength As Long, ByVal ulFlags As Long, ByVal hMachine As Long) As Long
'BOOL WINAPI CM_Locate_DevNodeA ( OUT PDEVINST pdnDevInst, IN DEVINSTID_A pDeviceID, IN ULONG ulFlags )
'BOOL WINAPI CM_Request_Device_Eject_ExA ( IN DEVINST dnDevInst, OUT PPNP_VETO_TYPE pVetoType, IN LPSTR pszVetoName, IN ULONG ulNameLength, IN ULONG ulFlags, IN HMACHINE hMachine )
Private Function GetSerialNumber(ByVal strDeviceId As String) As String '在DeviceId中获取SerialNumber
Dim i As Integer
Dim Length As Integer
Length = Len(strDeviceId)
For i = Length To 1 Step -1
If Mid(strDeviceId, i, 1) = "/" Then
GetSerialNumber = Mid(strDeviceId, i + 1, Length - i - 1)
Exit Function
End If
Next
End Function
Private Sub GetUsbDevices() '获取所有usb分区
Dim strWQL As String
Dim objSWbemServices As SWbemServices, objWmiObject As SWbemObject, objWmiObjectSet As SWbemObjectSet, objPattions As SWbemObjectSet, objPattion As SWbemObject
Dim objLogicalDiskToPartitions As SWbemObjectSet, objLogicalDiskToPartition As SWbemObject
If ConnectWmiServer(objSWbemServices, ".") Then
strWQL = "Select * From Win32_DiskDrive where InterfaceType='USB'"
Set objPattions = objSWbemServices.ExecQuery(strWQL)
For Each objPattion In objPattions
strWQL = "Associators of {win32_DiskDrive.DeviceID='" & objPattion.DeviceID & "'} where AssocClass = Win32_DiskDriveToDiskPartition"
Set objWmiObjectSet = objSWbemServices.ExecQuery(strWQL)
For Each objWmiObject In objWmiObjectSet
Debug.Print objWmiObject.Description; objWmiObject.Name; objWmiObject.PNPDeviceID; objWmiObject.Index
strWQL = "Associators of {Win32_DiskPartition.DeviceID='" & objWmiObject.DeviceID & "'} where AssocClass = Win32_LogicalDiskToPartition"
Set objLogicalDiskToPartitions = objSWbemServices.ExecQuery(strWQL)
For Each objLogicalDiskToPartition In objLogicalDiskToPartitions
cboUsbDriveList.AddItem "<Disk:" & objPattion.Index & ":" & objWmiObject.Index + 1 & ">" & objLogicalDiskToPartition.Description & "(" & objLogicalDiskToPartition.Name & ")"
Next
Next
Next
If cboUsbDriveList.ListCount Then