Einzelnen Beitrag anzeigen

Andreas L.
(Gast)

n/a Beiträge
 
#1

Programm starten u. auf dessen Ende warten + Rückgabewert

  Alt 13. Jul 2009, 17:04
Manchmal ist es nötig von einem gestarteten Programm eine Antwort zu erhalten. Z. B. hat man ein Update-Programm und möchte wissen ob eine neue Version verfügbar ist oder das Update erfolgreich installiert wurde. Dazu kann man den ExitCode der Anwendung setzen. ExitCode ist eine Integer-Variable. Zur besseren Code-Lesbarkeit können wir uns noch einen eigenen Typen in den beiden Anwendungen definieren. Z. B.
Delphi-Quellcode:
  type
    TUpdateResult = (urSuccessful, urError);
In der zu startenden Anwendung (Update.exe) einfach im z. B. OnClose des MainForms oder nach ausführen einer Aktion:
Delphi-Quellcode:
  //globale Variable
  var
    MyUpdateResult: TUpdateResult;

...
...
  //Bsp.: Eine Datei kopieren und bei Erfolg den Wert
  //urSuccessful unserer globalen Variable zuweisen
  if CopyFile('Datei.exe', 'Datei.exe', False) then
    MyUpdateResult := urSuccessful
  else
    MyUpdateResult := urError;

...
...
  //Den Wert aus unserer Variable nach Integer casten und in die Variable ExitCode eintragen
  ExitCode := Integer(MyUpdateResult);
In der Hauptanwendung welche das Update z. B. bei einem ButtonClick startet, müssen wir uns nur noch TShellExecuteInfo, ShellExecuteEx, GetExitCodeProcess und WaitForSingleObject bedienen:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
   ExecuteInfo: TShellExecuteInfo;
   UpdateResult: TUpdateResult;
   Temp: Integer;
begin
  //Einstellungen setzen
  FillChar(ExecuteInfo, SizeOf(ExecuteInfo), 0);
  ExecuteInfo.cbSize := SizeOf(TShellExecuteInfo);
  with ExecuteInfo do
  begin
    fMask := SEE_MASK_NOCLOSEPROCESS;
    wnd := Application.Handle;

    //Auszuführende Anwendung
    lpFile := PChar('Update.exe');

    //auf Wunsch noch Parameter mitgeben
    //lpParameters := PChar('-EinParameter');

    //Wenn Update.exe im selben Verzeichnis wie die Hauptanwendung liegt, ansonsten anpassen!
    lpDirectory := PChar(ExtractFilePath(Application.ExeName));

    //Update.exe anzeigen, weitere Möglichkeiten SW_HIDE oder SW_MAXIMIZED, etc.
    nShow := SW_SHOWNORMAL;
  end;

  //Anwendung starten
  if not ShellExecuteEx(@ExecuteInfo) then
    RaiseLastOSError;

  //Warten bis Update.exe beendet wird, anstatt INFINITE kann man auch eine
  //Wartezeit in Milisekunden übergeben z. B. 120000 für 2 Min.
  WaitForSingleObject(ExecuteInfo.hProcess, INFINITE);

  //ExitCode holen
  GetExitCodeProcess(ExecuteInfo.hProcess, TempCode);

  //Handle schließen
  CloseHandle(ExecuteInfo.hProcess)

  //Nach TUpdateResult casten...
  UpdateResult := TUpdateResult(TempCode);

  //...und auswerten
  case UpdateResult of
    urError: ShowMessage('Es ist ein unbekannter Fehler aufgetreten!'); //Wie ich diese Fehlermeldung liebe ;-)
    urSuccessful: ShowMessage('Update wurde installiert :-)');
  end;

end;
  Mit Zitat antworten Zitat