VB.NET-Tipp 0055: Hinzufügen und Entfernen von USB-Wechselmedien erkennen
von Robert Closheim
Beschreibung
Mit dieser Klasse ist es möglich festzustellen, ob bzw. wann ein USB-Wechselmedium (USB-Stick oder USB-Festplatte) hinzugekommen ist oder entfernt wurde.
Schwierigkeitsgrad: | Framework-Version(en): .NET Framework 2.0, .NET Framework 3.0, .NET Framework 3.5 | .NET-Version(en): Visual Basic 2005, Visual Basic 2008 | Download: |
' Dieser Quellcode stammt von http://www.activevb.de ' und kann frei verwendet werden. Für eventuelle Schäden ' wird nicht gehaftet. ' Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum. ' Ansonsten viel Spaß und Erfolg mit diesem Source! ' Projektversion: Visual Studio 2005 ' Option Strict: An ' ' Referenzen: ' - System ' - System.Data ' - System.Deployment ' - System.Drawing ' - System.Windows.Forms ' - System.Xml ' ' Imports: ' - Microsoft.VisualBasic ' - System ' - System.Collections ' - System.Collections.Generic ' - System.Data ' - System.Drawing ' - System.Diagnostics ' - System.Windows.Forms ' ' ############################################################################## ' ########################### DriveChangeWatcher.vb ############################ ' ############################################################################## ' Mit dieser Klasse ist es möglich festzustellen, ob ein Laufwerk hinzugekommen ' ist oder entfernt wurde. An dieser Stelle möchte ich mich für die tatkräftige ' Unterstützung von Frank Schüler bedanken, von ihm wurde ich auf den ' folgenden Link aufmerksam gemacht: ' http://msdn2.microsoft.com/en-us/library/aa363239(VS.85).aspx ' Diesen möchte ich dem interessiertem Leser wärmstens empfehlen. Ebenso vielen ' Dank an Eckard Ahlers für das Korrekturlesen und die kleinen Tipps am Rande. Public Class DriveChangeWatcher Inherits System.Windows.Forms.NativeWindow ' Das sind die Ereignisse aus WParam. ' Uns interessiert nur, ob ein Laufwerk hinzugekommen ist oder ' entfernt wurde. Public Event DriveArrived(ByVal sender As Object, _ ByVal e As System.IO.DriveInfo) Public Event DriveRemoved(ByVal sender As Object, _ ByVal e As System.IO.DriveInfo) ' Die Struktur für OEM. ' Wird über LParam gefüllt. ' USB-Sticks laufen alle hier auf. Private Structure DEV_BROADCAST_OEM Dim dbco_size As Integer Dim dbco_devicetype As Integer Dim dbco_reserved As Integer Dim dbco_identifier As Integer Dim dbco_suppfunc As Integer End Structure ' Die Struktur für Volumes. ' Wird über LParam gefüllt. Private Structure DEV_BROADCAST_VOLUME Dim dbch_size As Integer Dim dbch_devicetype As Integer Dim dbch_reserved As Integer Dim dbcv_unitmask As Integer Dim dbcv_flags As Short End Structure ' Die Struktur für den Header. ' Wird über LParam gefüllt. Private Structure DEV_BROADCAST_HDR Dim dbch_size As Integer Dim dbch_devicetype As Integer Dim dbch_reserved As Integer End Structure ' Das sind die Konstanten der Gerätetypen ' Vorsicht die Gerätetypen Variablen in den Strukturen sind vom Typ Integer. ' IntelliSense kann das nicht auflösen. Private Enum DeviceType OEM = 0 DEVNODE = 1 VOLUME = 2 PORT = 3 NET = 4 DEVICEINTERFACE = 5 HANDLE = 6 End Enum ' Dies sind die Konstanten für die verschiedenen Geräte - Habe ich zur der ' besseren Verwendbarkeit in eine Enum gepackt.(siehe oben) ' // type of device in DEV_BROADCAST_HDR ' // OEM- or IHV-defined: ' Public Const DBT_DEVTYP_OEM As Integer = &H0& ' Devnode number. ' Public Const DBT_DEVTYP_DEVNODE As Integer = &H1& ' // Logical volume ' Public Const DBT_DEVTYP_VOLUME As Integer = &H2& ' // Port (serial or parallel) ' Public Const DBT_DEVTYP_PORT As Integer = &H3& ' // Network resource ' Public Const DBT_DEVTYP_NET As Integer = &H4& ' // Device interface class ' Public Const DBT_DEVTYP_DEVICEINTERFACE As Integer = &H5& ' // File system handle ' Public Const DBT_DEVTYP_HANDLE As Integer = &H6& ' Windowmessage DeviceChange Private Const WM_DEVICECHANGE As Integer = &H219 'Die beiden Ereignisse, die für uns von Bedeutung sind. Private Const DBT_DEVICEARRIVAL As Integer = &H8000 Private Const DBT_DEVICEREMOVECOMPLETE As Integer = &H8004 ' Dies ist der Dreh- und Angelpunkt der Klasse. - Hier bekommen wir die ' Messages mit. ' In unserm Fall interessiert uns nur die WM_DeviceChange-Nachricht Protected Overrides Sub WndProc(ByRef m As Message) If m.Msg = WM_DEVICECHANGE Then Me.HandleHeader(m) End If MyBase.WndProc(m) End Sub ' Hier schauen wir erst mal in den Header und verzweigen dementsprechend Private Sub HandleHeader(ByRef m As Message) Dim header As DEV_BROADCAST_HDR Dim objHeader As Object = m.GetLParam(header.GetType) If Not IsNothing(objHeader) Then 'Dient nur zur Kennzeichnung, was nicht implementiert ist Dim notSupported As Boolean Select Case header.dbch_devicetype Case DeviceType.OEM Me.HandleOEM(m) Case DeviceType.DEVNODE notSupported = True Case DeviceType.VOLUME Me.HandleVolume(m) Case DeviceType.PORT notSupported = True Case DeviceType.NET notSupported = True Case DeviceType.DEVICEINTERFACE notSupported = True Case DeviceType.HANDLE notSupported = True End Select End If End Sub ' Das Ereignis betrifft ein Volume Private Sub HandleVolume(ByRef m As Message) Dim volume As DEV_BROADCAST_VOLUME Dim objVolume As Object = m.GetLParam(volume.GetType) If Not IsNothing(objVolume) Then volume = DirectCast(objVolume, DEV_BROADCAST_VOLUME) Dim di As New IO.DriveInfo(Me.DriveFromMask(volume.dbcv_unitmask)) ' USB-Stick If di.DriveType = IO.DriveType.Removable Then If CInt(m.WParam) = DBT_DEVICEARRIVAL Then RaiseEvent DriveArrived(Me, di) End If End If ' USB-Festplatte If di.DriveType = IO.DriveType.Fixed Then If CInt(m.WParam) = DBT_DEVICEARRIVAL Then RaiseEvent DriveArrived(Me, di) End If End If If CInt(m.WParam) = DBT_DEVICEREMOVECOMPLETE Then RaiseEvent DriveRemoved(Me, di) End If End If End Sub ' OEM, und was genau? ' Uns interesieren nur Volumes Private Sub HandleOEM(ByRef m As Message) Dim oem As DEV_BROADCAST_OEM Dim objOem As Object = m.GetLParam(oem.GetType) If Not IsNothing(objOem) Then oem = DirectCast(objOem, DEV_BROADCAST_OEM) If oem.dbco_devicetype = DeviceType.VOLUME Then Me.HandleVolume(m) End If End If End Sub ' Liefert uns den Laufwerksbuchstaben zurück Private Function DriveFromMask(ByVal unitmask As Integer) As Char For b As Integer = 0 To 25 If (unitmask And CInt(2 ^ b)) <> 0 Then Return Chr(65 + b) End If Next b End Function '################################################################# ' Wir haben zwei Möglichkeiten der Instanzierung '################################################################# ' Erste Möglichkeit: ' Wir benötigen das Form in der die Klasse instanziert wird. ' Und müssen den Handle der Form auf unser NativeWindow setzen. Public Sub New(ByVal form As System.Windows.Forms.Form) Me.AssignHandle(form.Handle) End Sub Private Sub New() End Sub ' Das Handle wieder freigeben. Protected Overrides Sub Finalize() Me.ReleaseHandle() MyBase.Finalize() End Sub ''################################################################## '' Zweite Möglichkeit:(Auskommentiert) '' Wir machen uns unser eigenes Handle. '' In diesen Fall benötigen wir das Form nicht! 'Public Sub New() ' Me.CreateHandle(New CreateParams) 'End Sub '' Das selbst erstellte Handle zerstören. 'Protected Overrides Sub Finalize() ' Me.DestroyHandle() ' MyBase.Finalize() 'End Sub End Class ' ############################################################################## ' ################################# Form1.vb ################################### ' ############################################################################## Public Class Form1 Private WithEvents myDriveWatcher As New DriveChangeWatcher(Me) Private Sub myDriveWatcher_DriveCoutChanged(ByVal sender As Object, _ ByVal e As System.IO.DriveInfo) Handles myDriveWatcher.DriveArrived MsgBox("Arrived -> " & e.Name & " - " & e.DriveType.ToString) End Sub Private Sub myDriveWatcher_DriveRemoved(ByVal sender As Object, _ ByVal e As System.IO.DriveInfo) Handles myDriveWatcher.DriveRemoved MsgBox("Removed -> " & e.Name & " - " & e.DriveType.ToString) End Sub End Class
Ihre Meinung
Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.
Archivierte Nutzerkommentare
Klicken Sie diesen Text an, wenn Sie die 1 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.
Kommentar von MAR am 24.06.2010 um 20:52
WOW, hat mir sehr, sehr, sehr geholfen bei meinem Projekt! Vielen Dank!!!
PS: Hab die Volumes noch um einen CD/DVD-Eintrag erweitert!