function DoExecuteAndWait(Filename, Parameter:
string; StartParams: TExecuteParams = []): LongWord
{ExitCode};
var
SEI: TShellExecuteInfo;
StartInfo: TStartupInfo;
ProcInfo: TProcessInformation;
LastError, Len: LongWord;
Error: EOSError;
Dialog: TForm;
Title, Username:
string;
Domain, Password:
string;
Host, Question:
string;
StartTime: LongWord;
Objects:
array[0..1]
of THandle;
Event: THandle;
begin
Result := LongWord(-1);
FillChar(SEI, SizeOf(SEI), 0);
SEI.cbSize := SizeOf(SEI);
SEI.fMask := SEE_MASK_NOCLOSEPROCESS
or SEE_MASK_FLAG_NO_UI;
if epOnlyWaitToIdleInput
in StartParams
then
SEI.fMask := SEI.fMask
or SEE_MASK_WAITFORINPUTIDLE;
SEI.Wnd := Application.MainFormHandle;
If epStartWithLogon
in StartParams
then
SEI.lpVerb := '
runas';
SEI.lpFile := PChar(Filename);
SEI.lpParameters := PChar(Parameter);
SEI.lpDirectory := PChar(ExtractFileDir(Filename));
SEI.nShow := SW_SHOWNORMAL;
if not ShellExecuteEx(@SEI)
then
RaiseLastOSError;
try
if StartParams * [epOnlyWaitToIdleInput, epNoWait] = []
then
if GetCurrentThreadId = MainThreadID
then begin
Dialog := CreateMessageDialog('
Warte auf ' + Filename, mtInformation, [mbAbort]);
try
Dialog.Show;
Title := Dialog.Caption;
Event := CreateEvent(
nil, False, False,
nil);
// dieses Event reagiert auf Messages im MainThread
try
Objects[0] := Event;
Objects[1] := SEI.hInstApp;
while True
do begin
Dialog.Caption := Format('
[%ds] ', [LongInt(GetTickCount - StartTime)
div 1000]) + Title;
Application.ProcessMessages;
if Dialog.ModalResult <> mrNone
then
raise Exception.Create('
DoExecuteAndWait: ' + Filename + sLineBreak + '
Abbruch durch den Benutzer.');
if Application.Terminated
then
raise Exception.Create('
DoExecuteAndWait: ' + Filename + sLineBreak + '
Programm wird beendet');
case MsgWaitForMultipleObjects(2, Objects, False, 5*60000, QS_ALLINPUT)
of
WAIT_OBJECT_0: ;
// Programm hat irgendwas zu erledigen
WAIT_OBJECT_0+1: Break;
// Programm beendet
WAIT_TIMEOUT: ;
// 5 Minuten lang nichts passiert? (ich glaub die Welt ist untergegangen)
WAIT_FAILED:
raise Exception.Create('
DoExecuteAndWait: ' + Filename + sLineBreak + '
Es war nicht möglich auf die Anwendung zu warten.');
else raise Exception.Create('
DoExecuteAndWait: ' + Filename + sLineBreak + '
Unbekannter Fehler.');
end;
end;
if not GetExitCodeProcess(SEI.hInstApp, Result)
then
Result := LongWord(-1);
finally
CloseHandle(Event);
end;
finally
Dialog.Free;
end;
end else
case WaitForSingleObject(SEI.hInstApp, 3*60000)
of
WAIT_OBJECT_0:
if not GetExitCodeProcess(SEI.hInstApp, Result)
then
Result := LongWord(-1);
WAIT_TIMEOUT:
raise Exception.Create('
DoExecuteAndWait: ' + Filename + sLineBreak + '
Gestartete Anwendung reagiert nicht. (innerhalb von 3 Minuten)');
WAIT_FAILED:
begin
LastError := GetLastError;
raise Exception.Create('
DoExecuteAndWait: ' + Filename + sLineBreak + SysErrorMessage(LastError));
end;
else raise Exception.Create('
DoExecuteAndWait: ' + Filename + sLineBreak + '
Unbekannter Fehler.');
end;
finally
CloseHandle(SEI.hInstApp);
end;
Exit;