Ich habe daran gearbeitet, das Einsetzen / Entfernen von USB zu erkennen. Ich habe Code mit CreateWindowEx () implementiert und übergebe eine WNCLASSEX mit meinem Fensterprozessrückruf. Wenn ich meinen USB einfüge und entferne, erhalte ich erfolgreich die WM_DEVICECHANGE Nachricht, aber der wParam wird immer auf DBT_DEVNODES_CHANGED festgelegt.
Ich bekomme weder DBT_DEVICEARRIVAL noch DBT_DEVICEREMOVECPLETE. Ich habe verwendet, was ich bekomme, aber ich muss wirklich in der Lage sein, den Unterschied zwischen Gerätankunft und -entfernung zu unterscheiden, so dass ich je nachdem, was ich bekomme, verschiedene Aktionen ausführen kann.
Im Moment muss ich einen Timer setzen, nachdem ich DBT_DEVNODES_CHANGED erhalten habe, und dann testen, ob es neue entfernbare Objekte auf dem System gibt oder ob irgendwelche in meiner Liste nicht mehr vorhanden sind. Ich bin mir sicher, dass das nicht stimmt, also dachte ich, ich würde fragen. Ich würde viel lieber den Timer loswerden und nur diese zwei Nachrichten erhalten. Das würde mir sehr dabei helfen, was ich tun muss. Irgendwelche Vorschläge?
Hier ist der Code, den ich für die Registrierung des Callbacks habe, sowie den Callback selbst:
HINWEIS: 3/12/2015: Code aktualisiert, um tatsächliche GUID und die Definition der DoRegisterDeviceInterfaceToHwnd () - Funktion anzuzeigen.):
%Vor%Wenn Sie die MSDN-Dokumentation lesen, heißt es:
Medieneinfügung oder -entfernung erkennen
Windows sendet alle übergeordneten Fenster eine Reihe von Standardmeldungen WM_DEVICECHANGE, wenn neue Geräte oder Medien (z. B. eine CD oder DVD) hinzugefügt und verfügbar werden und wenn vorhandene Geräte oder Medien entfernt werden . Sie müssen sich nicht registrieren, um diese Standard -Nachrichten zu erhalten. Weitere Informationen darüber, welche Nachrichten standardmäßig gesendet werden, finden Sie im Abschnitt "Hinweise" in RegisterDeviceNotification. .
RegisterDeviceNotification-Funktion
Jede Anwendung mit einem Fenster der obersten Ebene kann grundlegende Benachrichtigungen empfangen, indem sie die WM_DEVICECHANGE-Nachricht verarbeitet. Anwendungen können die RegisterDeviceNotification-Funktion verwenden, um sich für den Empfang von Gerätebenachrichtigungen zu registrieren.
...
Die Ereignisse DBT_DEVICEARRIVAL und DBT_DEVICEREMOVECOMPLETE werden automatisch an alle Fenster der obersten Ebene für Portgeräte gesendet . Daher ist es nicht erforderlich, RegisterDeviceNotification für ports aufzurufen, und die Funktion schlägt fehl, wenn das Member dbch_devicetype DBT_DEVTYP_PORT ist.
DBT_DEVTYP_PORT
0x00000003Port-Gerät (seriell oder parallel) . Diese Struktur ist eine DEV_BROADCAST_PORT-Struktur.
Ein USB-Gerät ist kein serieller / paralleler Anschluss. Es ist stattdessen eine Geräteschnittstelle ( DBT_DEVTYP_DEVICEINTERFACE
). Und DBT_DEVICEARRIVAL
/ DBT_DEVICEREMOVECOMPLETE
werden standardmäßig nicht für DBT_DEVTYP_DEVICEINTERFACE
devices gesendet . Wenn Sie sie wollen, müssen Sie RegisterDeviceNotification()
verwenden, um sie anzufordern.
Es sieht so aus, als ob Ihr Code auf diesem MSDN-Beispiel basiert:
Registrierung für Gerätebenachrichtigung
In diesem Code ist WceusbshGUID
als {25dbce51-6c8f-4a72-8a6d-b54c2b4fc835}
definiert, was als Klassenleitfaden für USB serial host PnP-Treiber kommentiert wird. Laut dieser MSDN-Seite:
Systemdefinierte Geräte-Setup-Klassen, die für Hersteller verfügbar sind
Diese GUID ist die Klassenanleitung für Windows CE USB ActiveSync-Geräte (die konsistenter mit dem im Code verwendeten Wceusb...
-Präfix ist). Auf dieser Seite ist auch {88BAE032-5A81-49f0-BC3D-A4FF138216D6}
für USB-Gerät ( alle USB-Geräte, die keiner anderen Klasse angehören ).
Der folgende CodeProject Artikel:
Hardwareeinfügung und / oder Entfernung erkennen
Erwähnungen {a5dcbf10-6530-11d2-901f-00c04fb951ed}
für USB Raw Device . Die gleiche GUID ist auf MSDN als GUID_DEVINTERFACE_USB_DEVICE
dokumentiert (deren Benennung) geht wahrscheinlich auf Pre-XP-Tage zurück, als die Benennung von Klassen-Guids und Interface-Guides war nicht gut getrennt ).
Wenn Sie also RegisterDeviceNotification()
mit einer spezifischen Klassen-Guid aufrufen, stellen Sie sicher, dass es sich um die korrekte Klassen-Guid handelt, da Sie Geräteereignisse nur dafür erhalten spezifischer Gerätetyp. Wahrscheinlich verwendet Ihr USB-Gerät eine andere Klassen-Guid als die, die Sie registrieren, und deshalb erhalten Sie nicht die Geräteereignisse, die Sie erwarten.
Wenn Sie beliebiges USB-Gerät unabhängig von seiner Klassen-Guid erkennen möchten (und mehrere USB-Klassen-Guids definiert sind), können Sie das DEVICE_NOTIFY_ALL_INTERFACE_CLASSES
Flag verwenden, wenn Sie RegisterDeviceNotification()
aufrufen Klassen-GUID wird ignoriert. In den Nachrichten " DBT_DEVICEARRIVAL
" und " DBT_DEVICEREMOVECOMPLETE
" (vorausgesetzt, Sie können sie jetzt abrufen) wird Ihnen die gemeldete dbcc_classguid
die tatsächliche Klassen-GUID mitteilen, und die gemeldete dbcc_name
beginnt mit dem \?\USB:
Präfix.
Eine letzte Sache - Sie erhalten nur DBT_DEVICE...
-Nachrichten, wenn ein USB-Gerät eingelegt / entfernt wird, während Ihre App bereits läuft. Um festzustellen, ob ein USB-Gerät beim Starten der App bereits angeschlossen ist, müssen Sie SetupAPI Funktionen ( SetupDiGetClassDevs()
, SetupDiEnumDeviceInterfaces()
, SetupDiGetDeviceInterfaceDetail()
usw.), um die verfügbaren Geräte aufzulisten.