Hallo miteinander Ich habe eine kleine Software die einen Daten-Stream mit einem MCU ermöglicht. Dabei werden Messwerte vom MCU an den PC gesendet. Der PC sendet ein paar Einstellungen an den MCU. Alles läuft soweit so gut. Nun bin ich am Überarbeiten der Software, damit diese etwas stabiler läuft: Wenn z.B die Verbindung getrennt wurde, erkennt dies die Software noch nicht und versucht einfach weiter Daten zu senden. Jetzt möchte ich dieses Problem beheben. Im gleichen Zug, könnte man ja noch eine "Auto-Connect" Funktion hinzufügen. Bis jetzt habe ich etwas über die Windows Device Notification Events gelesen, aber dies ist sehr sehr "kompliziert". Über einen Timer wäre dies lösbar, aber nicht so elegant... FTDI hat dafür eine App-Note herausgegeben, aber leider ist diese in C++ geschrieben und ich bräuchte diese in C#. Das wäre zwar nicht sonderlich schwer es umzuschreiben, wenn man es versteht... Hat jemand da einen Tipp? MFG Patrick
Nimm lieber den sauberen Weg über die WinAPI. RegisterForDeviceNotification() ist doch total einfach, das sind doch nur 2 Zeilen, um sich das Event anhand der GUID des Treibers generieren zu lassen.
Einfach? 2 Zeilen? Hier sind etwas mehr als 2 Zeilen... http://msdn.microsoft.com/en-us/library/aa363432%28v=VS.85%29.aspx Aber eventuell hast du ja ein besseres Beispiel. MFG
OK, 2 Zeilen sind nicht nur, aber viel mehr auch nicht. Ich programmiere mit der MFC, daher diese Lösung. Hab ich von hier: http://www.codeproject.com/KB/system/HwDetect.aspx
1 | BEGIN_MESSAGE_MAP(..., CDialog) |
2 | ...
|
3 | ON_MESSAGE(WM_DEVICECHANGE, OnMyDeviceChange) |
4 | ...
|
5 | END_MESSAGE_MAP() |
6 | |
7 | |
8 | BOOL Dialog::OnInitDialog() |
9 | {
|
10 | DEV_BROADCAST_DEVICEINTERFACE NotificationFilter; |
11 | ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) ); |
12 | NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); |
13 | NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; |
14 | |
15 | NotificationFilter.dbcc_classguid = GUID; |
16 | HDEVNOTIFY hDevNotify = RegisterDeviceNotification(this->GetSafeHwnd(), &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE); |
17 | |
18 | return TRUE; // return TRUE unless you set the focus to a control |
19 | }
|
20 | |
21 | LRESULT Dialog::OnMyDeviceChange(WPARAM wParam, LPARAM lParam) |
22 | {
|
23 | // for more information, see MSDN help of WM_DEVICECHANGE
|
24 | |
25 | // this part should not be very difficult to understand
|
26 | |
27 | if(wParam == DBT_DEVICEARRIVAL) |
28 | {
|
29 | |
30 | }
|
31 | |
32 | if(wParam == DBT_DEVICEREMOVECOMPLETE) |
33 | {
|
34 | |
35 | }
|
36 | |
37 | return 0; |
38 | }
|
Musst du natürlich bissl modifizieren und die Methoden deklarieren.
Ich steh gerade etwas auf dem Schlauch: Das ist die C++ Variante, oder? Geht das auch mit C#? Weil alle anderen Beispiele haben nie eine Message_Map...
Achso. Ich habs falsch gelesen, ich dachte du brauchst C++ und hast nur ein C# Beispiel. Sicher geht das auch in C#, da hab ich aber kein eigenes Beispiel parat. Viel mehr kann es dort aber auch nicht sein, und die Eventhandler sind ja in C# noch einfacher zu handhaben...
OK. Das Abfangen der Meldung, ob ein USB Gerät angeschlossen oder entfernt wurde habe ich mitlerweile:
1 | protected override void WndProc(ref Message m) |
2 | { |
3 | if (m.Msg == WM_DEVICECHANGE) |
4 | { |
5 | switch (m.WParam.ToInt32()) |
6 | { |
7 | case DBT_DEVICEARRIVAL: |
8 | MessageBox.Show(m.LParam.ToString()); |
9 | break; |
10 | |
11 | case DBT_DEVICEREMOVECOMPLETE: |
12 | MessageBox.Show(m.LParam.ToString()); |
13 | break; |
14 | } |
15 | } |
16 | base.WndProc(ref m); |
17 | } |
Jetzt ist einfach noch das Problem, dass der Event jedesmal kommt. Aber ich möchte ihn nur für ein Device. Die GUID habe ich... Kann ich da irgendwas noch hinzufügen?
In C++ kommst du über den LParam an die Device-Infos ran:
1 | if(wParam == DBT_DEVICEARRIVAL) |
2 | {
|
3 | PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam; |
4 | if(pHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) |
5 | {
|
6 | PDEV_BROADCAST_DEVICEINTERFACE pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr; |
7 | ...
|
8 | }
|
9 | }
|
An pDevInf hängt dann der Name, Gerätepfad, Class-GUID usw. da kannst du dir das passende raussuchen und nur was machen, wenn die GUID passt....ich vermute, das geht bei dir genau so.
Klapt leider nicht. Ich müsste die Events für ein ganz spezielles Device bekommen, da wenn z.B 2 FTDI Chips angeschlossen wurden und einer Entfernt wird, bekomme ich dann den selben Event... Werde noch etwas Suchen, aber irgendwie habe ich das Gefühl das hierfür C# nicht unbedingt geeignet ist.
Hm, du musst doch auch in C# den Gerätepfad usw. mit dem Event mitbekommen. Da musst du dann halt nach deiner genauen Seriennummer oder was auch immer suchen. Mit der C++ Variante und RegisterForDeviceNotification() bekommst du auch für alle Geräte, die mit der gleichen Treiber GUID laufen das Event.
Patrick B. schrieb: > Klapt leider nicht. > > Ich müsste die Events für ein ganz spezielles Device bekommen, da wenn > z.B 2 FTDI Chips angeschlossen wurden und einer Entfernt wird, bekomme > ich dann den selben Event... > > Werde noch etwas Suchen, aber irgendwie habe ich das Gefühl das hierfür > C# nicht unbedingt geeignet ist. http://social.msdn.microsoft.com/Forums/eu/csharpgeneral/thread/c4b7445f-9e1d-4b3e-b4a1-320d1d8b1ef7
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.