Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Autostart.exe beenden wenn CD ausgeworfen wird (https://www.delphipraxis.net/165322-autostart-exe-beenden-wenn-cd-ausgeworfen-wird.html)

Eagleeye 23. Dez 2011 15:06

Autostart.exe beenden wenn CD ausgeworfen wird
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo erstmal allen Nutzern dieses Forums,

ich arbeite grad an einem CD/DVD-Menü für ein Projekt. Es ist auch alles soweit schick und fertig.
Nur wenn die CD/DVD ausgeworfen wird während das Programm noch läuft gibt es folgende Fehlermeldung:

autostart.exe - Kein Datenträger (siehe angehängtes Bild)

Das Programm soll sich schlicht beenden beim CD-Auswurf, aber das tut es erst wenn man einmal die Fehlermeldung weggeklickt hat.

Das merkwürdige ist das die Meldung nur dann auftritt, wenn das Programm von einer echten CD ausgeführt wird.
Bei Ausführung des Programms von einem USB-Stick oder einem virtuellen CD-Laufwerk (Virtual CloneDrive 5.4.5.0) funktioniert es,
d.h. das Programm wird ohne Meldung beendet sobald der Stick abgezogen wird oder wenn das Image unmounted wird.

Ich verwende folgenden Code:
Delphi-Quellcode:
  {$SetPEFlags IMAGE_FILE_EXECUTABLE_IMAGE}
  {$SetPEFlags IMAGE_FILE_NET_RUN_FROM_SWAP}
  {$SetPEFlags IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP}
und

Delphi-Quellcode:
procedure TForm1.WMDeviceChange(var Msg: TMessage);
var
  ptr: PDev_Broadcast_HDR;
  volptr: PDev_Broadcast_Volume;
begin
  try
    if (Msg.WParam = DBT_DEVICEREMOVECOMPLETE) and (Msg.LParam <> 0) then
    begin
      ptr := Pointer(Msg.LParam);
      if ptr.dbch_devicetype = DBT_DEVTYP_VOLUME then
      begin
        volptr := Pointer(ptr);
        if UpperCase(ExtractFileDrive(Application.ExeName))[1] = GetDriveLetter(volptr^.dbcv_unitmask) then
          Application.Terminate;
      end;
    end;
  except
    {$IFDEF DEBUG}
      on E: Exception do
       ShowMessage('Fehler in WMDevicechange: ' + E.Message);
    {$ENDIF}
  end;
end;
Hab ein Testprojekt zusammen gestellt zum Download. Vielleicht hat von euch jemand ne gute Idee wie ich die Fehlermeldung unterdrücken kann.

Ansonsten wünsche ich allen schonmal ein frohes Weihnachtsfest.

MfG Eagleeye

DeddyH 23. Dez 2011 16:39

AW: Autostart.exe beenden wenn CD ausgeworfen wird
 
Nur so eine Idee: könntest Du nicht mit Code in der Art
Delphi-Quellcode:
var
  ErrMode: UINT;
begin
  ErrMode := SetErrorMode(SEM_FAILCRITICALERRORS);
  try
    //arbeiten
  finally
    SetErrorMode(ErrMode);
  end;
die System-Fehlermeldungen temporär an Dein Programm weiterleiten und anschließend den alten Zustand wiederherstellen?

himitsu 23. Dez 2011 20:30

AW: Autostart.exe beenden wenn CD ausgeworfen wird
 
Notfalls:

- Programm wird startet
- es schaut, ob es sich auf einer CD befindet (oder es schaut nicht und macht es einfach)
- es kopiert sich ins Temp-Verzeichnis
- es wird dort gestartet (eventuell mit parameter, damit es weiß, daß es schon dort ist)
- es prüft ob die CD noch drin ist (idealer Weise auf entsprechende Laufwerks-Einlege-/-Auswerfereignisse warten)
- und beendet sich dann, samt sich zu löschen

evetuel auch direkt nur einen Loader aufs Laufwerk, welcher das direkte Programm kopiert und startet

der "Loader"-Prozess beendet sich natürlich gleich wieder


PS: die virtuellen CD-Laufwerke werden gerne mal nicht richtig beendet, wenn noch etwas geöffnet ist.
Kenn ich zumindestens noch von VCCD4 so ... ist hier ja vielleicht auch noch so.

Eagleeye 3. Jan 2012 10:26

AW: Autostart.exe beenden wenn CD ausgeworfen wird
 
Erstmal allen ein frohes neues Jahr und danke für die schnelle Hilfe.

Zitat:

Zitat von DeddyH (Beitrag 1142932)
Nur so eine Idee: könntest Du nicht mit Code in der Art
Delphi-Quellcode:
var
  ErrMode: UINT;
begin
  ErrMode := SetErrorMode(SEM_FAILCRITICALERRORS);
  try
    //arbeiten
  finally
    SetErrorMode(ErrMode);
  end;
die System-Fehlermeldungen temporär an Dein Programm weiterleiten und anschließend den alten Zustand wiederherstellen?

Hab einfach mal das Form-Create wie folgt angepasst:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  WebBrowser1.Navigate(ExtractFilePath(Application.ExeName) + 'index.htm');
  SetErrorMode(SEM_FAILCRITICALERRORS);
end;
Die Fehlermeldung kommt jetzt nicht mehr und das Programm terminiert vernüftig.

Ich habs ins Form-Create eingefügt, da ich ja nicht genau weiß wann und wo (in welcher Routine) die Windows-Meldung hineinplatzt, aber ich vermute das meine Methode TForm1.WMDeviceChange(var Msg: TMessage) nicht auf das nicht bereite CD/DVD-Laufwerk zugreift.
Ich werd aber gleich mal den Aufruf von SetErrorMode() nach TForm1.WMDeviceChange verschieben und testen.

MfG Eagleeye

Eagleeye 5. Jan 2012 08:40

AW: Autostart.exe beenden wenn CD ausgeworfen wird
 
Hat etwas länger gedauert mit dem Testen...

Die Windowsfehler nur während der WMDeviceChange-Methode abzufangen funktioniert nicht und die Windows-Meldung beim CD-Auswurf kam trotzdem.
Werd also den Aufruf von SetErrorMode(SEM_FAILCRITICALERRORS) wohl schon im FormCreate ausführen müssen.
Jetzt stellt sich mir nur die Frage ob ich mir damit nicht irgendwelche unerwünschten Seiteneffekte einfange. So richtig schlau wurd ich aus den unvollständigen MSDN Einträgen zu dem Thema noch nicht, aber ich werd mal noch ein bischen schauen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:07 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz