我有将USB设备插入系统或从系统中拔出时发送电子邮件的请求。我使用ManagementEventWatcher来捕获此类事件。不过,我们遇到的情况是,USB驱动器出了点问题,并且它在某种程度上从系统中消失了(没有物理拔下)。我们尚未注意到任何通知,这意味着该事件似乎不在我们已使用的范围之内。有什么我可以添加到我的应用程序中来处理其他事情的工具,而不是像usb电源问题之类的Justus即插即用或其他与此有关的方法吗?请参阅下面的代码:
Imports System.Management
Public Class Usb
Public Event ReportEvent(information As String)
Private WithEvents _mediaConnectWatcher As ManagementEventWatcher
Private _usbDriveName As String
Private _uUsbDriveLetter As String
Private Enum InterfaceDriveType
Usb
End Enum
Private Async Function StartDetection() As Task
' __InstanceOperationEvent will trap both Creation and Deletion of class instances
Dim query2 As New WqlEventQuery("SELECT * FROM __InstanceOperationEvent WITHIN 1 " _
& "WHERE TargetInstance ISA 'Win32_DiskDrive'")
_mediaConnectWatcher = New ManagementEventWatcher
_mediaConnectWatcher.Query = query2
'AddHandler _mMediaConnectWatcher.EventArrived, AddressOf Arrived
Dim t As Task= Task.Run(sub() _mediaConnectWatcher.Start())
Await t
End Function
Public sub Arrived(sender As Object, e As EventArrivedEventArgs) Handles _mediaConnectWatcher.EventArrived
Try
'If InvokeRequired Then
' Invoke(New Action(Of Object, EventArrivedEventArgs)(AddressOf Arrived), sender, e)
'Else
Dim mbo, obj As ManagementBaseObject
'the first thing we have to do is figure out if this is a creation or deletion event
mbo = e.NewEvent
'next we need a copy of the instance that was either created or deleted
obj = CType(mbo("TargetInstance"), ManagementBaseObject)
Select Case mbo.ClassPath.ClassName
Case "__InstanceCreationEvent"
If String.Compare(obj("InterfaceType").ToString(), InterfaceDriveType.Usb.ToString, ignoreCase := true) = 0 Then
'ListBox1.Items.Add($"Interface type: {obj("InterfaceType")} Caption: {obj("Caption")} Drive letter: {GetDriveLetterFromDisk(obj("name"))} has been plugged in")
RaiseEvent ReportEvent($"Interface type: {obj("InterfaceType")} Caption: {obj("Caption")} Drive letter: {GetDriveLetterFromDisk(obj("name"))} has been plugged in")
Else
'ListBox1.Items.Add($"Interface: {obj("InterfaceType")}")
'RaiseEvent ReportEvent($"Interface: {obj("InterfaceType")}")
End If
Case "__InstanceDeletionEvent"
If String.Compare(obj("InterfaceType").ToString(), InterfaceDriveType.Usb.ToString, ignoreCase := true) = 0 Then
'ListBox1.Items.Add($"Interface type: {obj("InterfaceType")} Caption: {obj("Caption")} has been unplugged")
RaiseEvent ReportEvent($"Interface type: {obj("InterfaceType")} Caption: {obj("Caption")} has been unplugged")
If obj("Caption") = _usbDriveName Then
_uUsbDriveLetter = String.Empty
_usbDriveName = String.Empty
End If
Else
'ListBox1.Items.Add($"Interface: {obj("InterfaceType")}")
End If
Case Else
'ListBox1.Items.Add($"nope: {obj("Caption")}")
End Select
'End If
Catch ex As Exception
End Try
End sub
Private Function GetDriveLetterFromDisk(name As String) As String
Try
Dim oqPart, oqDisk As ObjectQuery
Dim mosPart, mosDisk As ManagementObjectSearcher
Dim objPart, objDisk As ManagementObject
Dim ans = String.Empty
' WMI queries use the "\" as an escape charcter
name = Replace(name, "\", "\\")
' First we map the Win32_DiskDrive instance with the association called
' Win32_DiskDriveToDiskPartition. Then we map the Win23_DiskPartion
' instance with the assocation called Win32_LogicalDiskToPartition
oqPart = New ObjectQuery("ASSOCIATORS OF {Win32_DiskDrive.DeviceID=""" & name & """} WHERE AssocClass = Win32_DiskDriveToDiskPartition")
mosPart = New ManagementObjectSearcher(oqPart)
For Each objPart In mosPart.Get()
oqDisk = New ObjectQuery("ASSOCIATORS OF {Win32_DiskPartition.DeviceID=""" & objPart("DeviceID") & """} WHERE AssocClass = Win32_LogicalDiskToPartition")
mosDisk = New ManagementObjectSearcher(oqDisk)
For Each objDisk In mosDisk.Get()
ans &= objDisk("name") & ","
Next
Next
Return ans.Trim(","c)
Catch ex As Exception
Return Nothing
End Try
End Function
Public Async function StartService() As task
await StartDetection()
End function
'Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
' m_MediaConnectWatcher.Stop()
' Application.Exit()
'End Sub
Public Sub StopService()
_mediaConnectWatcher.Stop()
End Sub
End Class