USB-Verbindung erkennen

  • VB.NET

Es gibt 31 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    USB-Verbindung erkennen

    Hallöchen,

    ich habe da ein kleines Problemchen: Ich muss meinem Lehrer für die Schule ein kleines Programm erstellen, welches automatisch eine USB-Verbindung erkennt und wenn ein USB-Gerät wieder entfernt wird.
    Dazu gehört ein USB-Stick, welches ich schon geschafft habe. Er möchte nur auch, dass es erkannt wird, wenn z.B. eine Tastatur, eine Maus oder sonstiges mit einer USB-Schnittstelle erkannt wird.

    Bisheriger vollständiger Code:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.IO
    2. Public Class Form1
    3. Private allDrives As New List(Of DriveInfo)
    4. Private Const WM_DEVICECHANGE As Integer = &H219
    5. Private Const DBT_DEVICEARRIVAL As Integer = &H8000
    6. Private Const DBT_DEVICEREMOVECOMPLETE As Integer = &H8004
    7. Protected Overloads Overrides Sub WndProc(ByRef msg As Message)
    8. MyBase.WndProc(msg)
    9. If msg.Msg = WM_DEVICECHANGE AndAlso msg.WParam = DBT_DEVICEARRIVAL Then
    10. 'Laufwerke suchen
    11. For Each s As String In Directory.GetLogicalDrives
    12. find_driveinfo_arg = s
    13. Dim d As DriveInfo = allDrives.Find(AddressOf find_driveinfo)
    14. If d Is Nothing Then
    15. 'Laufwerk ist neu
    16. Console.Beep(1000, 1500)
    17. 'Laufwerk zu "bereits vorhanden" hinzufügen
    18. allDrives.Add(New DriveInfo(s))
    19. End If
    20. Next
    21. End If
    22. If msg.Msg = WM_DEVICECHANGE AndAlso msg.WParam = DBT_DEVICEREMOVECOMPLETE Then
    23. 'alle laufwerke aus der liste prüfen
    24. Dim temp As List(Of DriveInfo) = GetAllDrives()
    25. For Each d As DriveInfo In allDrives
    26. find_driveinfo_arg = d.Name
    27. Dim lost As DriveInfo = temp.Find(AddressOf find_driveinfo)
    28. If lost Is Nothing Then
    29. 'Laufwerk wird in der Liste nicht mehr gefunden
    30. Console.Beep(1000, 3000)
    31. MsgBox("Ein USB-Gerät wurde entfernt.", MsgBoxStyle.Information, "USB-Alert")
    32. 'Laufwerk aus der Liste löschen
    33. allDrives.Remove(d)
    34. Exit For
    35. End If
    36. Next
    37. End If
    38. End Sub
    39. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    40. Me.Hide()
    41. Timer1.Interval = 10
    42. Timer1.Start()
    43. Me.Hide()
    44. allDrives = GetAllDrives()
    45. End Sub
    46. Private Function GetAllDrives() As List(Of DriveInfo)
    47. Dim ret As New List(Of DriveInfo)
    48. For Each d As String In Directory.GetLogicalDrives
    49. ret.Add(New DriveInfo(d))
    50. Next
    51. Return ret
    52. End Function
    53. 'Suchfunktion für die Liste
    54. Private find_driveinfo_arg As String
    55. Private Function find_driveinfo(ByVal d As DriveInfo)
    56. If d.Name = find_driveinfo_arg Then
    57. Return True
    58. Else
    59. Return False
    60. End If
    61. End Function
    62. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    63. Me.Hide()
    64. End Sub
    65. End Class


    Danke schon mal im Voraus.

    Grüße,
    Michi
    Du kannst es mit WMI versuchen, da gibt es div. Klassen wie z.B. Win32_PNPDevice
    Systeminformationen mit WMI auslesen ab .NET 3.0 oder früher
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!


    Schon mal Danke für die Hilfe. Ich glaube ich stelle mich gerade etwas blöd an.
    Wie muss ich das dann machen?
    Wenn ein USB-Gerät verbunden wird oder getrennt wird, soll der System-Lautsprecher angesteuert werden, also den Ton wiedergeben, wenn man öfter auf die Shift-Taste drückt.

    Was wäre das dann für ein Sourcecode?
    Habe den Code aus deinem Beitrag genommen, funktioniert aber nicht.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Management
    2. Public Class Form1
    3. ''' <summary>
    4. ''' Funktion um den Namen der CPU zu ermitteln
    5. ''' </summary>
    6. ''' <returns> String </returns>
    7. ''' <remarks></remarks>
    8. Shared Function getName() As String
    9. Try
    10. Dim searcher As New ManagementObjectSearcher( _
    11. "root\CIMV2", _
    12. "SELECT * FROM Win32_PNPDevice")
    13. For Each queryObj As ManagementObject In searcher.Get()
    14. Return >Hier muss ja die Reaktion des System-Lautsprechers sein<
    15. Next
    16. Catch err As ManagementException
    17. Return MsgBox("Error.", MsgBoxStyle.Critical, "USB-Alert.exe")
    18. End Try
    19. End Function
    20. End Class

    Dazu kommt bei dem letzten "End Function" ein Fehler. Er sagt "Von der Funktion "getName" wird nicht ina llen Codepfaden ein Wert zurückgegeben. Wenn das Ergebnis verwendet wird, kann zur Laufzeit eine NULL-Verweisausnahme auftreten."


    Danke.

    Grüße,
    Michi
    Was

    RIPENCE schrieb:

    funktioniert aber nicht
    :?:
    Du gehst per For Each durch alle Geräte und verlässt die Schleife beim ersten Gerät?
    Was muss passieren, wenn das dritte Dein gesuchtes Gerät ist?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Was muss passieren, wenn das dritte Dein gesuchtes Gerät ist?


    Aber darum geht's eig. gar nicht. Ich suche an sich kein Gerät. Ich möchte nur bzw. mein Lehrer möchte, dass wenn ein USB-Gerät (USB-Stick, Tastatur, Maus,...) eingsteckt oder getrennt wird, der Systemlautsprecher ein Piep Ton von sich gibt. :)

    RIPENCE schrieb:

    Ich suche an sich kein Gerät
    Sondern?
    Du willst bei Änderung der Konfiguration benachrichtigt werden. Dann solltest Du auch auf eine Information reagieren, die das System generiert.
    Wer ruft denn Deine Funktion getName() auf?
    Was hat MsgBox() für einen Rückgabewert?
    ---
    Fang an mit Option Strict On.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RIPENCE Würdest Du bitte auch die anderen Fragen beantworten?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    @RIPENCE Würdest Du bitte auch die anderen Fragen beantworten?


    Sorry, habe nur den Code von @Gather kopiert. Hier ist sein Post:
    Systeminformationen mit WMI auslesen ab .NET 3.0 oder früher
    Kenne mich damit nicht aus, habe noch nie mit solchen Dingen gearbeitet; ist also das Erste Mal mit USB-Verbindungen usw.

    Ich hatte eigentlich einen anderen Code, der hat zumindest erkannt, wenn ein USB-Stick eingesteckt wird.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.IO
    2. Public Class Form1
    3. Private allDrives As New List(Of DriveInfo)
    4. Private Const WM_DEVICECHANGE As Integer = &H219
    5. Private Const DBT_DEVICEARRIVAL As Integer = &H8000
    6. Private Const DBT_DEVICEREMOVECOMPLETE As Integer = &H8004
    7. Protected Overloads Overrides Sub WndProc(ByRef msg As Message)
    8. MyBase.WndProc(msg)
    9. If msg.Msg = WM_DEVICECHANGE AndAlso msg.WParam = DBT_DEVICEARRIVAL Then
    10. 'Laufwerke suchen
    11. For Each s As String In Directory.GetLogicalDrives
    12. find_driveinfo_arg = s
    13. Dim d As DriveInfo = allDrives.Find(AddressOf find_driveinfo)
    14. If d Is Nothing Then
    15. 'Laufwerk ist neu
    16. Console.Beep(1000, 1500)
    17. 'Laufwerk zu "bereits vorhanden" hinzufügen
    18. allDrives.Add(New DriveInfo(s))
    19. End If
    20. Next
    21. End If
    22. If msg.Msg = WM_DEVICECHANGE AndAlso msg.WParam = DBT_DEVICEREMOVECOMPLETE Then
    23. 'alle laufwerke aus der liste prüfen
    24. Dim temp As List(Of DriveInfo) = GetAllDrives()
    25. For Each d As DriveInfo In allDrives
    26. find_driveinfo_arg = d.Name
    27. Dim lost As DriveInfo = temp.Find(AddressOf find_driveinfo)
    28. If lost Is Nothing Then
    29. 'Laufwerk wird in der Liste nicht mehr gefunden
    30. Console.Beep(1000, 3000)
    31. MsgBox("Ein USB-Gerät wurde entfernt.", MsgBoxStyle.Information, "USB-Alert")
    32. 'Laufwerk aus der Liste löschen
    33. allDrives.Remove(d)
    34. Exit For
    35. End If
    36. Next
    37. End If
    38. End Sub
    39. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    40. Me.Hide()
    41. Timer1.Interval = 10
    42. Timer1.Start()
    43. Me.Hide()
    44. allDrives = GetAllDrives()
    45. End Sub
    46. Private Function GetAllDrives() As List(Of DriveInfo)
    47. Dim ret As New List(Of DriveInfo)
    48. For Each d As String In Directory.GetLogicalDrives
    49. ret.Add(New DriveInfo(d))
    50. Next
    51. Return ret
    52. End Function
    53. 'Suchfunktion für die Liste
    54. Private find_driveinfo_arg As String
    55. Private Function find_driveinfo(ByVal d As DriveInfo)
    56. If d.Name = find_driveinfo_arg Then
    57. Return True
    58. Else
    59. Return False
    60. End If
    61. End Function
    62. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    63. Me.Hide()
    64. End Sub
    65. End Class
    @RIPENCE

    RodFromGermany schrieb:

    Fang an mit Option Strict On.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RIPENCE schrieb:

    Wie schon bereits gesagt: Ich möchte, dass wenn man ein USB-Gerät verbindet oder trennt, dass der Systemlautsprecher ein Piep von sich gibt - mehr nicht.
    Naja, wenn du deinen eigenen Code verstündest, könntest du das Prob wohl mit Leichtigkeit lösen.

    zB das hier:

    VB.NET-Quellcode

    1. If msg.Msg = WM_DEVICECHANGE AndAlso msg.WParam = DBT_DEVICEARRIVAL Then
    2. ' der folgende Code
    Welche Bedingung muss passieren, damit der folgende Code ausgeführt wird?
    Nomen est Omen

    Was meinst du, warum heisst die erste der beiden Konstanten WM_DEVICECHANGE?

    RodFromGermany schrieb:

    Fang an mit Option Strict On.

    Habe ich gemacht, jetzt bekomme ich aber einen Fehler in der vorletzten Zeile End Function.

    Stimmt das so?

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.Management
    3. Public Class Form1
    4. ''' <summary>
    5. ''' Funktion um den Namen der CPU zu ermitteln
    6. ''' </summary>
    7. ''' <returns> String </returns>
    8. ''' <remarks></remarks>
    9. Shared Function getName() As String
    10. Try
    11. Dim searcher As New ManagementObjectSearcher( _
    12. "root\CIMV2", _
    13. "SELECT * FROM Win32_PNPDevice")
    14. For Each queryObj As ManagementObject In searcher.Get()
    15. Return queryObj("Name").ToString
    16. Next
    17. Catch err As ManagementException
    18. Return CStr(MsgBox("Error.", MsgBoxStyle.Critical, "USB-Alert.exe"))
    19. End Try
    20. End Function
    21. End Class

    RIPENCE schrieb:

    Stimmt das so?
    Nö.
    Ruf die MessageBox auf und gib einen Leerstring zurück.
    Warum verfolgst Du nicht die WndProc-Methode? Die scheint doch gut zu funktionieren.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    ErfinderDesRades schrieb:

    Naja, wenn du deinen eigenen Code verstündest, könntest du das Prob wohl mit Leichtigkeit lösen.

    An sich passt es doch? Er meldet sich, sobald ein USB-Stick angesteckt wurde. Leider nicht, wenn z.B. eine Tastatur oder eine Maus eingesteckt wird.

    RodFromGermany schrieb:

    Nö.
    Ruf die MessageBox auf und gib einen Leerstring zurück.
    Warum verfolgst Du nicht die WndProc-Methode? Die scheint doch gut zu funktionieren.

    Ich habe mich noch nie mit der Verbindung der USB-Sticks und VB.NET befasst. Ich mache das hier zum ersten mal und habe lediglich im Internet nach vielen Sourcecodes gesucht.

    RIPENCE schrieb:

    Leider nicht, wenn z.B. eine Tastatur oder eine Maus eingesteckt wird.
    Ein USB-Dongle wird auch nicht erkannt.
    Probierst Du:

    VB.NET-Quellcode

    1. Private Const DBT_DEVNODES_CHANGED As Integer = 7

    VB.NET-Quellcode

    1. If msg.Msg = WM_DEVICECHANGE AndAlso wParam = DBT_DEVNODES_CHANGED Then
    2. MessageBox.Show("Ein USB-Gerät wurde gesteckt / entfernt.", "USB-Alert", MessageBoxButtons.OK, MessageBoxIcon.Information)
    3. End If
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    er passt fast.
    Daher ist nun die Frage, ob du durch Denken (und meine Frage beantworten) selbst drauf kommen möchtest - und also deinen Code verstehen - oder ob du nur was funktionierendes vorgesagt haben möchtest.

    Ich wiederhole nochmal meine Frage:

    ErfinderDesRades schrieb:

    VB.NET-Quellcode

    1. If msg.Msg = WM_DEVICECHANGE AndAlso msg.WParam = DBT_DEVICEARRIVAL Then
    2. ' der folgende Code

    Welche Bedingung muss passieren, damit ' der folgende Code ausgeführt wird?
    Wenn die Frage iwie unklar ist, dann teil das bitte mit.
    Nicht die Frage ignorieren, sonst ignoriere ich deine Fragen selbstverständlich auch.

    RodFromGermany schrieb:

    Probierst Du:


    RodFromGermany schrieb:

    RIPENCE schrieb:

    Leider nicht, wenn z.B. eine Tastatur oder eine Maus eingesteckt wird.
    Ein USB-Dongle wird auch nicht erkannt.
    Probierst Du:

    VB.NET-Quellcode

    1. Private Const DBT_DEVNODES_CHANGED As Integer = 7

    VB.NET-Quellcode

    1. If msg.Msg = WM_DEVICECHANGE AndAlso wParam = DBT_DEVNODES_CHANGED Then
    2. MessageBox.Show("Ein USB-Gerät wurde gesteckt / entfernt.", "USB-Alert", MessageBoxButtons.OK, MessageBoxIcon.Information)
    3. End If


    Schon mal Danke! Er erkennt nun alles (Tastatur, Maus...).
    Was mir aber aufgefallen ist, ist das er das immer gleich zwei mal meldet. Also ich stecke es aus: Drücke "OK". Danach kommt nochmal eine MsgBox.
    Das ist jetzt mein gesamter Code:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Const WM_DEVICECHANGE As Integer = &H219
    3. Private Const DBT_DEVNODES_CHANGED As Integer = 7
    4. Protected Overloads Overrides Sub WndProc(ByRef msg As Message)
    5. MyBase.WndProc(msg)
    6. If msg.Msg = WM_DEVICECHANGE AndAlso msg.WParam = DBT_DEVNODES_CHANGED Then
    7. MsgBox("Gerät enfernt/hinzugefügt.")
    8. End If
    9. End Sub

    Sonst macht er immer alles drei mal.


    ErfinderDesRades schrieb:

    er passt fast.
    Daher ist nun die Frage, ob du durch Denken (und meine Frage beantworten) selbst drauf kommen möchtest - und also deinen Code verstehen - oder ob du nur was funktionierendes vorgesagt haben möchtest.

    Ich wiederhole nochmal meine Frage:

    ErfinderDesRades schrieb:

    VB.NET-Quellcode

    1. If msg.Msg = WM_DEVICECHANGE AndAlso msg.WParam = DBT_DEVICEARRIVAL Then
    2. ' der folgende Code

    Welche Bedingung muss passieren, damit ' der folgende Code ausgeführt wird?
    Wenn die Frage iwie unklar ist, dann teil das bitte mit.
    Nicht die Frage ignorieren, sonst ignoriere ich deine Fragen selbstverständlich auch.


    Es muss WM_DEVICECHANGE und DBT_DEVICEARRIVAL jeweils True sein.
    Also es muss sich was geändert haben und dazu muss noch etwas angekommen sein.

    RIPENCE schrieb:

    gesamter Code
    Schmeiß nicht den gut funktionierenden Code raus.
    Kläre auf, warum die Meldung zwei Mal kommt und fange das geeignet ab.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    RIPENCE schrieb:

    gesamter Code
    Schmeiß nicht den gut funktionierenden Code raus.
    Kläre auf, warum die Meldung zwei Mal kommt und fange das geeignet ab.


    Funktioniert aber auch ohne? O.o
    Ah, schon klar warum die Meldung jetzt zwei mal kommt..
    Dort steht ja AndAlso, es sind also beide Bedingungen auf True. Dort muss also einfach nur ein or rein, oder?

    //Edit
    ​or funktioniert schon mal nicht. Sorry, ich komme gerade echt nicht weiter.