Ermitteln ob bestimmtes USB Gerät angeschlossen ist

  • VB.NET

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von diylab.

    Ermitteln ob bestimmtes USB Gerät angeschlossen ist

    Hallo zusammen,

    ich arbeite gerade an einem kleinen Tool um eine Startumgebung für eine Software zu konfigurieren. Der Benutzer kann dabei verschiedene Versionen, Bibliotheken und Einstellungen auswählen, die dann beim Start entsprechend aufgerufen werden.

    Die Software ist Lizenz geschützt, hierbei gibt es 2 Mögliche Lizensierungen.

    Zum einen über eine Floating Lizenz per Netzwerk Server, oder Lokal per USB Hardlock

    Damit ich beim Aufbau der Umgebung weis, welche Lizenz ich ansteuern muss habe ich nach langem Googeln einen Code gefunden um alle angeschlossenen USB-Geräte per WMI auslesen zu können, und diesen an meine Bedürfnisse angepasst


    VB.NET-Quellcode

    1. Function FindUSBDevice(ByRef str As String) As Boolean
    2. Dim TempA As String = "Select * from Win32_USBControllerDevice"
    3. Dim TempB As String = "Select * From Win32_PnPEntity Where DeviceID = '"
    4. Dim Suche As String = ""
    5. Try
    6. Dim mos As ManagementObjectSearcher = New ManagementObjectSearcher(TempA)
    7. Dim moc As ManagementObjectCollection = mos.Get()
    8. For Each mo As ManagementObject In moc
    9. Dim Dependent As String = mo("Dependent").ToString().Replace("""", "")
    10. Dim Device As String = Dependent.Substring(Dependent.IndexOf("=") + 1)
    11. Dim Search As ManagementObjectSearcher = New ManagementObjectSearcher(TempB & Device & "'")
    12. Dim Col As ManagementObjectCollection = Search.Get()
    13. For Each Items As ManagementObject In Col
    14. Suche = (Items("Description").ToString())
    15. If InStr(Suche, str) > 0 Then Return True
    16. Next
    17. Next
    18. Return False
    19. Catch
    20. MsgBox("Fehler beim Auslesen der USB Geräte", , "Fehler")
    21. End Try
    22. End Function


    und rufe diesen dann so auf

    VB.NET-Quellcode

    1. If FindUSBDevice("SafeNet Inc. HASP Key") = True Then
    2. MsgBox("Hardlock wurde gefunden", , "Hardlock Suche")
    3. Else
    4. MsgBox("Hardlock wurde nicht gefunden", , "Hardlock Suche")
    5. End If


    Das ganze funktioniert auch Super, nur dauert dies auf meinem kleinen Privatrechner wo nichts angeschlossen ist ca. 10 Sekunden und auf meinem Firmenrechner vo recht viel angeschlossen ist ca. 25 Sekunden, und ich kann den Benutzer beim Start der Software keine 25 Sekunden warten lassen.

    Ich suche jetzt eine Möglichkeit quasi ohne lange Wartezeiten zu ermitteln ob das Hardlock angeschlossen ist !!

    Hat jemand eine Idee ??

    Gruß
    Dolzman
    @Dolzman

    Ich kann mich damit nicht so aus, aber ich habe das hier gefunden:
    developerfusion.com/article/84338/making-usb-c-friendly/
    »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais
    ich kann den Benutzer beim Start der Software keine 25 Sekunden warten lassen.
    Ist es nur eine Lizenzkontrolle?
    Wirf die Hardwaresuche in einen Hintergrund-Thread und mach zunächst mal weiter, wie wenn alles OK wäre.
    Erst wenn du das Hardlock definitv nicht findest, unterbrichst du und bittest den User, es einzustecken.
    Oder benötigst du Daten von dem Teil um mit dem Programm überhaupt arbeiten zu können?
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Lizenzprüfung mache ich damit keine, ich ermittle nur welche Umgebung gestartet werden soll, auf dem Hardlock befinden sich die Schnittstellen Lizenzen, mit denen ich Daten von Fremdsystemen Importieren / Exportieren kann, auf dem Floating Server die normale Arbeitsumgebung. Wenn ich Daten in ein Fremdsystem exportieren will, wird das Hardlock angesteckt ich mache also nur Doppelklick auf die Datei, das Tool Startet, ermittelt die Lizenzumgebung, schreibt die Konfigurationsdateien und startet die Software. Also würde eine Hintergrundprüfung nichts bringen, da ich dann auch erst warten muss bis die Hardlockprüfung abgeschlossen ist.

    Edit:
    Mit der devcon.exe von Microsoft (CMD Tool vom Gerätemanager) kann man die USB devices recht schnell auslesen, benötigt aber Adminrechte, weswegen dies leider nich funktioniert!

    Gruß
    Dolzman

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Dolzman“ ()

    Hallo Mr. Dolzman,

    vielleicht könntest Du mal folgendes probieren...
    Ich habe vor einiger Zeit mal einen Dateimanager gebraucht, der schnell auf angeschlossene Laufwerke reagieren musste.
    Dazu benutzte ich folgende Klasse (ExplorerDrivewatcher.vb):

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Explicit On
    2. Option Strict On
    3. Imports System.IO
    4. Public Class ExplorerDrivewatcher
    5. Inherits System.Windows.Forms.NativeWindow
    6. 'Konstanten für Windowsmessages
    7. Private Const WM_DEVICECHANGE As Integer = &H219
    8. Private Const DBT_DEVICEARRIVAL As Integer = &H8000
    9. Private Const DBT_DEVICEREMOVECOMPLETE As Integer = &H8004
    10. 'Events
    11. Public Event WinProc(ByVal sender As ExplorerDrivewatcher, ByRef m As Message)
    12. Public Event Drive_Neu(ByVal DI As DriveInfo)
    13. Public Event Drive_entfernt(ByVal DN As String)
    14. Private allDrives As New List(Of DriveInfo)
    15. Public Sub New(ByVal Handle As IntPtr)
    16. 'übergibt dem NativeWindow das Handle
    17. MyBase.AssignHandle(Handle)
    18. 'Listet alle Laufwerke in allDrives
    19. allDrives = GetAllDrives()
    20. End Sub
    21. 'Ausgabemöglichkeit für Laufwerkliste
    22. Public Function Getdrives() As List(Of DriveInfo)
    23. Return allDrives
    24. End Function
    25. 'WinProc-Methode des übergebenen Handles
    26. Protected Overrides Sub WndProc(ByRef msg As Message)
    27. 'gibt die OriginalMessage an übergebenes Handles weiter
    28. MyBase.WndProc(msg)
    29. 'Event für externe Auswertung der Message
    30. RaiseEvent WinProc(Me, msg)
    31. 'Wenn ein Laufwerk gewechselt und ein neues Laufwerk erkannt wurde
    32. If msg.Msg = WM_DEVICECHANGE AndAlso msg.WParam = CType(DBT_DEVICEARRIVAL, IntPtr) Then
    33. 'alle laufwerke durchlaufen und in der liste suchen
    34. For Each s As String In Directory.GetLogicalDrives
    35. find_driveinfo_arg = s
    36. Dim d As DriveInfo = allDrives.Find(AddressOf find_driveinfo)
    37. If d Is Nothing Then
    38. d = New DriveInfo(s)
    39. 'laufwerk wurde in der liste nicht gefunden und ist somit neu
    40. 'MessageBox.Show("Neuer Datenträger erkannt = " & d.Name)
    41. 'laufwerk jetzt zur liste hinzufügen
    42. allDrives.Add(d)
    43. 'Event auslösen
    44. RaiseEvent Drive_Neu(d)
    45. End If
    46. Next
    47. End If
    48. 'Wenn ein Laufwerk gewechselt und ein Laufwerk entfernt wurde
    49. If msg.Msg = WM_DEVICECHANGE AndAlso msg.WParam = CType(DBT_DEVICEREMOVECOMPLETE, IntPtr) Then
    50. 'alle laufwerke aus der liste prüfen
    51. Dim temp As List(Of DriveInfo) = GetAllDrives()
    52. For Each d As DriveInfo In allDrives
    53. find_driveinfo_arg = d.Name
    54. Dim lost As DriveInfo = temp.Find(AddressOf find_driveinfo)
    55. If lost Is Nothing Then
    56. 'laufwerk wurde in der liste nicht mehr gefunden
    57. 'MessageBox.Show("Datenträger wurde entfernt = " & d.Name)
    58. 'Event auslösen
    59. RaiseEvent Drive_entfernt(d.Name)
    60. 'laufwerk aus der liste entfernen
    61. allDrives.Remove(d)
    62. 'schleife verlassen
    63. Exit For
    64. End If
    65. Next
    66. End If
    67. End Sub
    68. 'Funktion zum Auflisten der Laufwerke
    69. Private Function GetAllDrives() As List(Of DriveInfo)
    70. Dim ret As New List(Of DriveInfo)
    71. 'und wieder befüllen
    72. For Each d As String In Directory.GetLogicalDrives
    73. ret.Add(New DriveInfo(d))
    74. Next
    75. Return ret
    76. End Function
    77. 'suchfunktion zum finden der laufwerke in der collection
    78. Private find_driveinfo_arg As String
    79. Private Function find_driveinfo(ByVal d As DriveInfo) As Boolean
    80. If d.Name = find_driveinfo_arg Then
    81. Return True
    82. Else
    83. Return False
    84. End If
    85. End Function
    86. End Class



    Benutzt wurde sie dann im Form so:

    VB.NET-Quellcode

    1. #Region " Deklarationen"
    2. ' Instanzierung der Laufwerksüberwachung mit Fensterhandle
    3. Dim Drivewatcher As New ExplorerDrivewatcher(Me.Handle)
    4. #End Region
    5. #Region " Load Form"
    6. Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
    7. ' Events
    8. AddHandler Drivewatcher.Drive_Neu, AddressOf LW_erkannt
    9. AddHandler Drivewatcher.Drive_entfernt, AddressOf LW_entfernt
    10. End Sub
    11. #End Region
    12. #Region " Überwachung der Laufwerke"
    13. ' Event Laufwerk neu
    14. Private Sub LW_erkannt(ByVal DI As DriveInfo)
    15. DirectoryTreeview1.RefreshTree()
    16. End Sub
    17. ' Event Laufwerk entfernt
    18. Private Sub LW_entfernt(ByVal Name As String)
    19. DirectoryTreeview1.RefreshTree()
    20. End Sub
    21. #End Region


    In den Events kannst Du dann so reagieren, wie es Dein Programm möchte.

    LG,
    Bruno
    Das Hardlock ist allerdings kein Laufwerk, und wird im Explorer auch nicht angezeigt, denke dass diese Variante deshalb nicht funktionieren wird. Ich werde mal versuchen die devcon.exe mit einzubinden, was einbauen um einen Adminuser zu hinterlegen, und dann die devcon.exe mit Adminrechten ausführen. Wenn ich nichts anderes finde wird das die einzige Möglichkeit sein.

    support.microsoft.com/kb/311272/de

    Gruß
    Dolzman
    Ich hab´s geschafft 8-) :) 8o :thumbup: :thumbsup: :D

    Und es war einfacher als ich gedacht habe. In meiner Verzweiflung habe ich versucht herauszufinden ob sich in der Registery irgendetwas ändert sobald ich das Hardlock anschließe, habe den HKLM Baum einmal mit und einmal ohne Hardlock exportiert und dann verglichen, und tatsächlich ändern sich einige Schlüssel

    Im Schlüssel HKLM\System\CurrentControlSet\Services befidet sich eine Auflistung sämtlicher USB Geräte die am Rechner angeschlossen sind oder waren, der Schlüssel "akshasp" gehört zum Hardlock, draunter befindet sich ein Schlüssel "Enum" und darin ein Wert "Count" ist das Hardlock dran, steht dieser auf 1, wenn nicht, auf 0.

    Und so kann ich im Bruchteil einer Sekunde ermitteln ob das HL aktiv ist, das funktioniert übrigens auch mit allen anderen USB Geräten, mann muss nur wissen welcher Schlüssel zu welchen Gerät gehört !! Und das auch noch ohne Adminrechte und externe Tools !!! :thumbup:

    VB.NET-Quellcode

    1. Dim MeinKey As RegistryKey
    2. Dim Inhalt As Integer
    3. Try
    4. MeinKey = Registry.LocalMachine.OpenSubKey("SYSTEM\CurrentControlSet\services\akshasp\Enum")
    5. Inhalt = MeinKey.GetValue("Count", "")
    6. MeinKey.Close()
    7. Catch ex As Exception
    8. MsgBox("Fehler beim lesen", , "Registery")
    9. End Try
    10. If Inhalt = 1 Then
    11. MsgBox("Hardlock ist angeschlossen", , "HASP Suche")
    12. Else
    13. MsgBox("Hardlock ist nicht angeschlossen", , "HASP Suche")
    14. End If


    8-) 8-) 8-)