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;