2010-10-12 16 views
11

Wissen Sie, welche API oder welche Sequenz von API-Aufrufen Windows verwendet, um die Funktion "Eject" auszuführen, die im Shell-Kontextmenü für austauschbare Volumes verfügbar ist?Wie wird ein USB-Wechseldatenträger/Volume ausgeworfen, ähnlich der "Auswerfen" -Funktion im Windows Explorer?

Bisher habe ich versucht, zwei Dinge:

  1. CM_Request_Device_Eject verwenden, aufzuzählen ich die Festplatten (mit dem SetupDiXXX APIs), finden die, die ich interessiert bin, gehen die Geräte-Manager-Hierarchie (Verwenden CM_XXX APIs) und schließlich Anruf CM_Request_Device_Eject auf der devInst des Geräts, das ich interessiere. Dieses funktioniert in dem Sinne, dass es die Volumes von Arbeitsplatz entfernt und macht das Gerät "sicher zu entfernen" (bereit, entfernt werden) aber es ist nicht dasselbe wie das Shell-Kontextmenü "Auswerfen" -Funktion. Die Art, wie ich das weiß ist, weil das Gerät, das ich ausstoßen will etwas tun soll, wenn es ausgeworfen wird und dass etwas nicht passiert, wenn ich den Auswurf mit CM_Request_Device_Eject.

  2. mit DeviceIoControl mit dem IOCTL_STORAGE_EJECT_MEDIA Steuercode. Die Abfolge der Ereignisse ist:

    Dies funktioniert überhaupt nicht. Jeder der DeviceIoControl Aufrufe schlägt mit ERROR_IVALID_FUNCTION (0x00000001) fehl. Ich weiß nicht, warum die Anrufe fehlschlagen. Ich habe festgestellt, dass weitere Anrufe funktionieren für die gleiche Datei-Handle (wie IOCTL_STORAGE_GET_DEVICE_NUMBER)

Schließlich meine Entwicklung Maschine läuft Windows 7 x64, und um DeviceIOControl die zweite Methode zu arbeiten, ich zu bekommen habe versucht, meine Anwendung mit Administratorrechten auszuführen, und das hat nichts geändert.

EDIT

Schließlich fand ich heraus, wo ich einen Fehler mit Ansatz # 2 zu machen war. Es stellt sich heraus, dass ich aus irgendeinem Grund den gewünschten Zugriff nicht richtig eingestellt habe, wenn ich den Griff zum Volume mit CreateFile geöffnet habe. Der korrekte Zugriffsmodus ist GENERIC_READ | GENERIC_WRITE und ich passierte 0. Nach der Korrektur meines Fehlers konnte ich das Gerät mit DeviceIoControl - IOCTL_STORAGE_EJECT_MEDIA, sowie mit Methode # 1, CM_Request_Device_Eject erfolgreich auswerfen.

Und es stellt sich heraus, dass Methode # 2 tatsächlich die Methode ist, die von der "Auswerfen" -Funktion des Shell-Kontextmenüs verwendet wird. Mit dieser Methode reagiert das Gerät korrekt.

+0

Ihr Ansatz # 2 sollte funktionieren. Auf http://stackoverflow.com/questions/58670/windows-cdrom-eject hat mir die Antwort von Andreas Magnusson geholfen, einen USB-Stick auszuwerfen. Die einzige Änderung war, seine Schreibweise von "DeviceIoControl" zu korrigieren. – Nate

+0

Außerdem gibt 'DeviceIoControl' bei Erfolg '1' zurück. Wenn Sie den Fehler 'ERROR_INVALID_FUNCTION' erhalten, ist das der Rückgabewert von 'DeviceIoControl' oder gibt es '0' zurück und Sie rufen' GetLastError' auf? – Nate

+0

@Nate: DeviceIoControl gibt 0 zurück, wenn ich es mit einem der Steuercodes, die ich erwähnte, aufrufe. Wenn ich dann GetLastError() aufrufen, gibt es 1 zurück, was ERROR_INVALID_FUNCTION ist. –

Antwort

1

Schließlich fand ich heraus, wo ich einen Fehler mit Ansatz # 2 machte.

Es stellt sich heraus, dass ich aus irgendeinem Grund den gewünschten Zugriff nicht korrekt beim Öffnen des Handle auf das Volume mit CreateFile festgelegt habe.

Der korrekte Zugriffsmodus ist GENERIC_READ | GENERIC_WRITE und ich passierte 0. Nachdem ich meinen Fehler korrigiert hatte, konnte ich das Gerät erfolgreich mit DeviceIoControl - IOCTL_STORAGE_EJECT_MEDIA, sowie mit Methode # 1 mit CM_Request_Device_Eject auswerfen.

Schließlich stellt sich heraus, dass Methode # 2 tatsächlich die Methode ist, die von der "Auswerfen" -Funktion des Shell-Kontextmenüs verwendet wird. Mit dieser Methode reagiert das Gerät korrekt.

0

Versuchen Sie zu folgen How to Prepare a USB Drive for Safe Removal, die zeigt, wie man CM_Request_Device_Eject Funktion verwendet.

+0

Danke @Oleg, aber dieser Ansatz ist genau das, was ich als Lösung # 1 beschrieben habe, das funktioniert, indem es USB auswirft, aber es tut nichts, was sonst Windows macht, wenn Sie im Shell-Kontextmenü auf "Auswerfen" klicken. Das ist, was ich brauche .. –

+0

@Miky Dinescu: Warum müssen Sie genau wissen, was Windows im Shell-Kontextmenü tun? Ich vermute, dass Sie einen Weg haben müssen, der funktioniert und keine Administratorrechte benötigt. Der Artikel aus dem Codeprojekt ist alt genug, Sie können das vollständige Codebeispiel herunterladen, das funktioniert. Warum müssen Sie wissen, wie das Shell-Kontextmenü aussieht? – Oleg

+0

Da das Auswerfen des Geräts aus der Windows-Shell eine Aktion auf diesem Gerät auslöst - kurz gesagt, eine LED leuchtet auf. Wenn ich das Gerät mithilfe der Methode CM_Request_Device_Eject aus meiner Anwendung ausstoße, wird das Gerät ausgeworfen, aber die LED leuchtet nicht. Und ja, ich habe überprüft, es ist das gleiche wie die Implementierung des Code-Projekts. Und ich bin ziemlich vertraut mit dem, was bereits in den Foren da draußen verfügbar ist - einschließlich CodeProject - da ich zwei Tage lang im Internet gesucht habe, um herauszufinden, wie es funktioniert. Hast du noch andere Vorschläge? –

0

Ich kam zufällig während einer Suche auf "CM_Request_Device_Eject" hierher und sah, dass es ähnlich zu einer Lösung war, die ich kürzlich gemacht hatte, indem ich ähnliche Teile einer Lösung zusammenzog. Verzeihen Sie die späte Antwort.

Ich habe die Schritte, die ich dafür gemacht habe, in meinem Projekt in this SO answer zusammengefasst.

+0

Ich habe tatsächlich meine eigene Frage beantwortet a vor einigen Jahren (siehe die Änderung in der Frage). Danke für das Einspielen. –