gpt4 book ai didi

.net - 使用 DeviceWatcher 监控 USB 驱动器并检索设备信息?

转载 作者:行者123 更新时间:2023-12-04 02:02:06 26 4
gpt4 key购买 nike

我是 WinForms 开发人员和我已经知道如何使用 WMI 监控连接或断开连接的 USB,但不久前我发现了 DeviceWatcher现代 Windows 应用程序的类,该类第一次感兴趣,因为似乎是一个非常改进和有效的替代方案,可以替代所有解释如何通过 Internet 监视驱动器的“旧”WMI 代码,但直到昨天(感谢 this post ) 我不知道如何在 WinForms 项目中使用 DeviceWatcher,但现在我在 WinForms 项目中使用 DeviceWatcher。

问题是也许我错了,但我认为这不是我所期望的,只是我找不到任何关于 DeviceWatcher 的文档(只有上面的 MSDN 示例),我找不到方法检索必要的信息来监视驱动器事件,我试图处理 DeviceWatcher 的所有事件,以便在调试控制台中打印出参数中包含的所有数据,希望能找到可以帮助我的东西......但是不,我非常坚持使用 设备观察者 上课,我无法想象如何进行。

当我连接或断开 USB 时,我只看到两件事,硬件 ID 和“InterfaceEnabled”属性(我不知道这是否决定了设备可用性),没有什么更有趣的了。

What I have accomplished:



· 检索硬件设备 ID。

What I would like to accomplish:



· 当设备连接、断开和断开时检索设备类型(USB 和其他类型设备的区别)。

· 在设备连接、断开和断开连接时检索设备可用性(我的意思是设备是否可以在其上读取/写入数据)。

· 在设备连接、断开和断开连接时检索设备信函。

· 在设备连接、断开和断开时检索设备标签描述。

The code:


Public Class DeviceWatcher_Test

Private WithEvents dw As DeviceWatcher = DeviceInformation.CreateWatcher

' It's suposed that these properties should exist in the "e.properties" on the "dw_updated" event?, not in my case.
' Dim props As String() = {"System.ItemNameDisplay", "System.Devices.ModelName", "System.Devices.Connected"}

Private Sub Test() Handles MyBase.Load

dw.Start()

End Sub

Private Sub dw_Added(ByVal sender As DeviceWatcher, ByVal e As DeviceInformation) _
Handles dw.Added

Dim sb As New System.Text.StringBuilder

With sb
.AppendLine("dw_added")
.AppendLine("********")
.AppendLine(String.Format("Interface ID.: {0}", e.Id))
.AppendLine(String.Format("Friendly Name: {0}", e.Name))
.AppendLine(String.Format("Is Enabled?..: {0}", e.IsEnabled))
End With

Debug.WriteLine(sb.ToString)

End Sub

Private Sub dw_Removed(ByVal sender As DeviceWatcher, ByVal e As DeviceInformationUpdate) _
Handles dw.Removed

Dim sb As New System.Text.StringBuilder

With sb
.AppendLine("dw_Removed")
.AppendLine("**********")
.AppendLine(String.Format("Interface ID:{0}", e.Id))

For Each item As KeyValuePair(Of String, Object) In e.Properties
.AppendLine(String.Format("TKey:{0}, TVal:{1} (TVal Type:{2})",
item.Key, item.Value.ToString, item.Value.GetType.Name))
Next

End With

Debug.WriteLine(sb.ToString)

End Sub

Private Sub dw_Updated(ByVal sender As DeviceWatcher, ByVal e As DeviceInformationUpdate) _
Handles dw.Updated

Dim sb As New System.Text.StringBuilder

With sb
.AppendLine("dw_Updated")
.AppendLine("**********")
.AppendLine(String.Format("Interface ID: {0}", e.Id))

For Each item As KeyValuePair(Of String, Object) In e.Properties

If item.Key.EndsWith("InterfaceEnabled", StringComparison.OrdinalIgnoreCase) Then
Dim Result As Boolean = CBool(item.Value)
' I'm not sure whether the 'Result' value really determines this:
.AppendLine(String.Format("The device is accessible?:{0}", CStr(Result)))

Else
.AppendLine(String.Format("TKwy:{0}, TVal:{1} (TVal Type:{2})",
item.Key, item.Value.ToString, item.Value.GetType.Name))

End If

Next

End With

Debug.WriteLine(sb.ToString)

End Sub

Private Sub dw_Stopped(ByVal sender As DeviceWatcher, ByVal e As Object) _
Handles dw.Stopped

Dim sb As New System.Text.StringBuilder

With sb
.AppendLine("dw_Stopped")
.AppendLine("**********")
.AppendLine(String.Format("e:{1} (e Type:{2})",
e.ToString, e.GetType.Name))

End With

Debug.WriteLine(sb.ToString)

End Sub

Private Sub dw_EnumerationCompleted(ByVal sender As DeviceWatcher, ByVal e As Object) _
Handles dw.EnumerationCompleted

If e IsNot Nothing Then

Dim sb As New System.Text.StringBuilder

With sb
.AppendLine("EnumerationCompleted")
.AppendLine("********************")
.AppendLine(String.Format("e:{1} (e Type:{2})",
e.ToString, e.GetType.Name))

End With

Debug.WriteLine(sb.ToString)

End If

End Sub

End Class

最佳答案

这将监视 USB 驱动器的到达和移除,并报告 DriveLetter、卷标和设备序列号。为了您的方便,它引发了 2 个事件:

Public Event DeviceAdded(sender As Object, e As USBWatcherEventArgs)
Public Event DeviceRemoved(sender As Object, e As USBWatcherEventArgs)

这只会监视添加/删除的新驱动器,它不会检测诸如弹出或插入 CD 或将媒体插入读卡器插槽之类的事情。
Imports System.Management

Public Class USBWatcher

' alternate method to use one event with an extra
' event property to report the action
'Public Enum WatcherActions
' DriveInserted = 1
' DriveRemoved = 2
'End Enum

' USB device added/removed args
Public Class USBWatcherEventArgs
Inherits EventArgs

'Public Property WatcherAction As WatcherActions
Public Property DriveLetter As String
Public Property VolumeName As String
Public Property VolumeSerial As String

Friend Sub New(drv As String, vol As String, ser As String)
DriveLetter = drv
VolumeName = vol
VolumeSerial = ser
'WatcherAction = act
End Sub

End Class

Private WithEvents Watcher As ManagementEventWatcher

Public Event DeviceAdded(sender As Object, e As USBWatcherEventArgs)
Public Event DeviceRemoved(sender As Object, e As USBWatcherEventArgs)

Private pnpCol As Dictionary(Of String, Management.ManagementObject)

Public Sub New()

End Sub

Public Sub StartWatching()

' get USBs currently attached
pnpCol = GetUSBDevices()

Dim arriveQuery = New WqlEventQuery("Select * from Win32_DeviceChangeEvent")
Watcher = New ManagementEventWatcher(arriveQuery)

' we are watching you
Watcher.Start()

End Sub

Public Sub StopWatching()
Watcher.Stop()

End Sub

Private Function GetUSBDevices() As Dictionary(Of String,
Management.ManagementObject)

Dim col As New Dictionary(Of String, Management.ManagementObject)

Dim moSearch As New Management.ManagementObjectSearcher("Select * from Win32_LogicalDisk")
Dim moReturn As Management.ManagementObjectCollection = moSearch.Get


For Each mo As Management.ManagementObject In moReturn
'Console.WriteLine("====")
'DebugProperties(mo)

' some USB external drives report as DriveType 3 (local disk), but are
' in fact removable. So monitor all disk drives.
If col.ContainsKey(mo("DeviceID").ToString) = False Then
col.Add(mo("DeviceID").ToString, mo)
End If

Next

Return col
End Function

Private inEvent As Boolean = False

Private Sub arrive_EventArrived(ByVal sender As Object,
ByVal e As System.Management.EventArrivedEventArgs) _
Handles Watcher.EventArrived

If inEvent Then Exit Sub
inEvent = True

Dim col As Dictionary(Of String, Management.ManagementObject) = GetUSBDevices()

Select Case col.Count
Case Is > pnpCol.Count
' device arrived
ProcessArrival(col)
Case Is < pnpCol.Count
' device removed
ProcessRemoval(col)
Case Is = pnpCol.Count
' noise...this is a chatty rascal
End Select

inEvent = False

End Sub

Private Sub ProcessArrival(col As Dictionary(Of String,
Management.ManagementObject))
For Each kvp As KeyValuePair(Of String,
Management.ManagementObject) In col
If pnpCol.ContainsKey(kvp.Key) = False Then

'Console.WriteLine("{0} {1} ", kvp.Key, kvp.Value)
'DebugProperties(kvp.Value)

Dim ea As New USBWatcherEventArgs(kvp.Value("DeviceID").ToString,
SafeString(kvp.Value("VolumeName")),
SafeString(kvp.Value("VolumeSerialNumber")))

RaiseEvent DeviceAdded(Me, ea)

'rebuild baseline for next event
pnpCol = col

End If
Next

End Sub

Private Sub ProcessRemoval(col As Dictionary(Of String,
Management.ManagementObject))
For Each kvp As KeyValuePair(Of String,
Management.ManagementObject) In pnpCol
If col.ContainsKey(kvp.Key) = False Then

'Console.WriteLine("{0} {1} ", kvp.Key, kvp.Value)
'DebugProperties(kvp.Value)

Dim ea As New USBWatcherEventArgs(kvp.Value("DeviceID").ToString,
SafeString(kvp.Value("VolumeName")),
SafeString(kvp.Value("VolumeSerialNumber")))

RaiseEvent DeviceRemoved(Me, ea)

'rebuild baseline for next event
pnpCol = col

End If
Next

End Sub

' lots of things can be NOTHING depending on the manufacturer's
' attention to detail. try to avoid NRE
Private Function SafeString(obj As Object) As String

If obj.GetType Is GetType(String) Then
Return CType(obj, String)
Else
If obj IsNot Nothing Then
Return obj.ToString
Else
Return "???"
End If
End If

End Function

' debug tool to poll a management object to get the properties and values
Private Sub DebugProperties(mo As Management.ManagementObject)

For Each pd As PropertyData In mo.Properties
If pd.Value IsNot Nothing Then
Console.WriteLine("{0} {1}", pd.Name,
If(pd.Value IsNot Nothing,
pd.Value.ToString,
"Nothing"))
End If

Next
End Sub

End Class

如何实现 USBWatcher
' local variable to catch events
Private WithEvents watcher As USBWatcher

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

watcher = New USBWatcher
watcher.StartWatching() ' or add to a button click
' I DONT have it starting automatically when you create the watcher

End Sub

Device Watcher 在不同的线程上运行,因此如果您想向控件发布通知,则必须使用委托(delegate):
Delegate Sub AddListItem(text As String)
Private myDelegate As AddListItem = New AddListItem(AddressOf AddNewListItem)

Private Sub AddNewListItem(text As String)
myListBox.Items.Add(text)
End Sub

然后从设备添加事件,例如:
Private Sub watcher_DeviceAdded(sender As Object, 
e As USBWatcher.USBWatcherEventArgs) Handles watcher.DeviceAdded

Console.Beep()

Dim msg As String = String.Format("Drive {0} ({1}) {2}",
e.DriveLetter,
e.VolumeName, "Inserted")
If myListBox.InvokeRequired Then
myListBox.Invoke(myDelegate, New Object() {msg})
Else
myListBox.Items.Add(msg)
End If

End Sub

DeviceRemoved 与消息文本中的第三个参数“Removed”不同。

USBWatcher 还有一个 StopWatching关闭观察器一段时间的方法, StartWatching启动并重新启动它。您的应用程序应该调用 StopWatching当应用程序结束时以防止 COM 错误;只需添加 watcher.StopWatching在表单关闭事件中。

这可以满足您的要求 - 在插入可移动媒体时引发事件并返回有关它们的信息 - 只是不完全符合您的要求。它使用久经考验的 WMI 而不是 Win8 方法,该方法在 MSDN 上只有稀疏的文档,并且只能在 Win8 上工作。

关于.net - 使用 DeviceWatcher 监控 USB 驱动器并检索设备信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24944865/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com