function ExecAndWait2(Filename, Params:
String; WindowState: Word = SW_SHOWNORMAL): Integer;
const
cError = -1;
cWait = 0;
cNoWait = -2;
var
ShExecInfoW : SHELLEXECUTEINFOW;
ExitInfo : PExitThreadDebugInfo;
wndLstAll,
wndLst : TStringList;
i, a : Integer;
procedure AllProcessToLst(Lst: TStringList);
function EnumWindowsProcA(Wnd: HWND; LParam: TStringList): BOOL;
stdcall;
begin
result := True;
if IsWindowVisible(Wnd)
then
begin
LParam.Add(IntToStr(Wnd));
end;
end;
begin
EnumWindows(@EnumWindowsProcA, integer(Lst));
end;
begin
Result := cError;
if (Filename <> '
')
and FileExists(FileName)
then
begin
ShExecInfoW.Wnd := GetForegroundWindow;
ShExecInfoW.cbSize := SizeOf(SHELLEXECUTEINFOW);
ShExecInfoW.fMask := SEE_MASK_NOCLOSEPROCESS;
ShExecInfoW.lpVerb := '
open';
ShExecInfoW.lpFile := PWideChar(WideString(Filename));
ShExecInfoW.lpParameters := PWideChar(WideString(Params));
ShExecInfoW.lpDirectory := PWideChar(WideString(ExtractFileDir(Filename)));
ShExecInfoW.nShow := WindowState;
wndLstAll := TStringList.Create;
try
AllProcessToLst(wndLstAll);
if ShellExecuteExW(@ShExecInfoW)
then
begin
result := cNoWait;
try
if ShExecInfoW.hProcess <> 0
then
begin
WaitForInputIdle(ShExecInfoW.hProcess, INFINITE);
New(ExitInfo);
FillChar(ExitInfo.dwExitCode, SizeOf(ExitInfo.dwExitCode), 0);
repeat
Application.ProcessMessages;
sleep(500);
GetExitCodeProcess(ShExecInfoW.hProcess, ExitInfo.dwExitCode);
until not(ExitInfo.dwExitCode = STILL_ACTIVE);
Dispose(ExitInfo);
Result := cWait;
end
else
// neues Handle ermitteln und auf dessen Beendigung warten:
begin
wndLst := TStringList.Create;
try
sleep(500);
// warten bis App geöffnet ist
AllProcessToLst(wndLst);
for i := wndLst.Count - 1
downto 0
do
if wndLstAll.IndexOf(wndLst[i]) > -1
then
wndLst.Delete(i);
if wndLst.Count > 0
then
// auf Beendigung warten:
begin
repeat
Application.ProcessMessages;
sleep(500);
wndLstAll.Clear;
AllProcessToLst(wndLstAll);
a := 0;
for i := 0
to wndLst.Count - 1
do
if wndLstAll.IndexOf(wndLst[i]) > -1
then
inc(a);
until a < wndLst.Count;
result := cWait;
end;
finally
wndLst.Free
end;
end;
finally
CloseHandle(ShExecInfoW.hProcess);
end;
end;
finally
wndLstAll.Free;
end;
end;
end;