Windows neue Hardware gefunden -> Laufwerksbuchstabe auslesen ?



  • Hi,

    also ich hab ne Software geschrieben, mit der ich WIA-fähige Geräte bedienen kann, also je nach Wunsch alle Bilder, nur das aktuellste kopieren, alle Eigenschaften (WIA-Version, Firmware-Version, GUID...) des Device zurückgeben usw.
    Mein Ziel ist es, dass ich auch Geräte bedienen kann, die als "normaler" Wechseldatenträger im Windows erscheinen.

    Meine Frage: Kann man über die Meldung, die im Win erscheint, wenn ein neues Gerät verbunden ist, den Buchstabe des jeweiligen Gerätes auslesen ? 😕
    Oder über einen anderen Weg ?

    Hat das schonmal jemand gemacht bzw. jemand Erfahrung damit?

    Bedanke mich jetzt schonmal für alle Antworten ! 👍



  • Du kannst auf die Nachricht WM_DEVICECHANGE und hier auf das Event DBT_DEVICEARRIVAL reagieren. Dazu gibt es im PSDK ein Beispiel unter "Detecting Media Insertion or Removal" Das Ganz einfach noch auf .Net umschreiben, dann sollte es klappen.



  • Ok, muss ich mir in Ruhe anschauen.

    Also wird die Message genauso verschickt, wenn ich ein bereits installiertes Device nur am PC anstecke ?
    So entnehme ich das der MSDN.
    Und dann würden die nötigen Infos wie z.b. Laufwerksbuchstabe in LPARAM stehen ?

    Sieht sehr gut aus.
    Werde es ausprobieren und mich wieder melden !

    Danke erstmal. 👍



  • Hi, also hab das erstmal soweit gemacht, dass ich auf die Win-Message reagiere.

    Die Frage ist eben nun, woher ich den Laufwerksbuchstabe bekomme ! 😕
    In der DEV_BROADCAST_VOLUME Struktur ist ein WORD, das Bit für Bit alle Laufwerke enthält.
    Nur sehe ich daran ja auch nicht, welchen Laufwerksbuchstaben das Device nun hat !



  • In dbcv_unitmask aus DEV_BROADCAST_VOLUME stehen alle Laufwerksbuchstaben, die die neue Hardware hat. Im Normalfall für einen USB-Stick steht hier nur ein Buchstabe drin. Falls aber mehrere Partitionen vorhanden sind (USB-Festplatte), gibt es auch mehrere Laufwerksbuchstaben. Es ist also keine Auflistung aller momentan vorhandenen Laufwerksbuchstaben auf dem Rechner.



  • Achso, also kriege ich davon meinen ersehnten Buchstaben der neuen Hardware her.

    Aber mal noch etwas anderes:
    Vorab, ich habe ein Konsolenapplikation.

    Da ich ja diese Message empfangen will, muss ich ja die WndProc überschreiben.
    Habe das gemacht, dann meine Klasse von NativeWindow abgeleitet, Referenz zu System.Windows.Forms zum Projekt hinzugefügt.

    So, wie muss jetzt die Geschichte mit CreateHandle usw. aussehen ?
    Wenn ich das nich mache, erhalte ich ja auch logischerweise keine Win-Messages !

    CreateParams p = new CreateParams();
    p.Caption = "MyApp";
    p.ClassName = ???;
    ???
    CreateHandle(p);
    




  • Nunja soweit bin ich jetzt auch.
    Auch das Weiterleiten hab ich alles.

    Der Message-Loop funktioniert erstmal und läuft.
    Nur kriege ich anscheinend die Message aber nicht (Breakpoint springt nicht an).

    private const int WM_DEVICECHANGE = 0x0219;
    private const int DBT_DEVICEARRIVAL = 0x8000;
    private const int DBT_DEVTYP_VOLUME = 0x00000002;
    
    [StructLayout(LayoutKind.Sequential)]
    private struct DEV_BROADCAST_VOLUME
    {
        public uint dbcv_size;
        public uint dbcv_devicetype;
        public uint dbcv_reserved;
        public uint dbcv_unitmask;
    }
    
    private void Create()
    {
        CreateHandle(new CreateParams());
    }
    
    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_DEVICECHANGE)
        {
            int devType = Marshal.ReadInt32(m.LParam, 4);
            if (devType == DBT_DEVTYP_VOLUME)
            {
                DEV_BROADCAST_VOLUME volume = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_VOLUME));
            }
            base.WndProc(ref m);
        }
    }
    

    Sehe hier jetzt kein Fehler ! 😞

    EDIT: Muss ich vielleicht per RegisterNotification erst sagen, dass meine Anwendung diese Message empfangen soll ?
    Nur hat meine kein Handle (zumindest weiß ich nicht, wo ich das herkrieg), dass man da ja aber angeben muss !



  • Also erstmal muss ja so heißen:

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_DEVICECHANGE)
        {
            int devType = Marshal.ReadInt32(m.LParam, 4);
            if (devType == DBT_DEVTYP_VOLUME)
            {
                DEV_BROADCAST_VOLUME volume = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_VOLUME));
            }       
        }
        base.WndProc(ref m); // muss natürlich außerhalb der ifs stehen !!
    }
    

    Und dann krieg ich ne Exception geschmissen bei CreateHandle: Fehler beim Erstellen des Fensterhandles !
    Also muss mal noch wissen, wie ich konkret die CreateParam-Properties setzen muss.

    In einer Windows-Application funktioniert es bestens.
    Und ein Fenster will ich eig nicht haben !



  • Keiner nen Plan ?

    Ich will in meiner Konsolenanwendung einfach nur WM_DEVICECHANGE behandeln können !
    Muss ich denn dazu unbedingt ein Fenster haben ??? 😕



  • Ok, passt schon.

    Habs eben mit nem extra Window gelöst.


Anmelden zum Antworten