{!
<summary>
Executes a program and waits for it to terminate</summary>
<returns>
-1 in case of error, otherwise the programs exit code</returns>
<param name="FileName">contains executable name + any parameters.
Always use a full pathname, and enclose the name in double quotes
if it contains spaces. Rules are the same as for a command prompt.</param>
<param name="Visibility">
is one of the ShowWindow options, e.g. SW_SHOWNORMAL</param>
<remarks>
In case of error SysErrorMessage(GetlastError) will return an
error message. The routine will process paint messages and messages
send from other threads while it waits.</remarks>
}
function WinExecAndWait32V2(FileName:
string; Visibility: integer):
DWORD;
procedure WaitFor(processHandle: THandle);
var
msg: TMsg;
ret: DWORD;
begin
repeat
ret := MsgWaitForMultipleObjects(
1,
{ 1 handle to wait on }
processHandle,
{ the handle }
False,
{ wake on any event }
INFINITE,
{ wait without timeout }
QS_PAINT
or { wake on paint messages }
QS_SENDMESSAGE
{ or messages from other threads }
);
if ret = WAIT_FAILED
then
Exit;
{ can do little here }
if ret = (WAIT_OBJECT_0 + 1)
then begin
{ Woke on a message, process paint messages only. Calling
PeekMessage gets messages send from other threads processed. }
while PeekMessage(msg, 0, WM_PAINT, WM_PAINT, PM_REMOVE)
do
DispatchMessage(msg);
PeekMessage(msg, 0, 0, 0, PM_NOREMOVE);
// prevents ghosting
end;
until ret = WAIT_OBJECT_0;
end;
{ Waitfor }
var { V1 by Pat Ritchey, V2 by P.Below }
zAppName:
array[0..512]
of char;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
begin { WinExecAndWait32V2 }
StrPCopy(zAppName, FileName);
FillChar(StartupInfo, Sizeof(StartupInfo), #0);
StartupInfo.cb := Sizeof(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := Visibility;
if not CreateProcess(
nil,
zAppName,
{ pointer to command line string }
nil,
{ pointer to process security attributes }
nil,
{ pointer to thread security attributes }
false,
{ handle inheritance flag }
CREATE_NEW_CONSOLE
or { creation flags }
NORMAL_PRIORITY_CLASS,
nil,
{ pointer to new environment block }
nil,
{ pointer to current directory name }
StartupInfo,
{ pointer to STARTUPINFO }
ProcessInfo)
{ pointer to PROCESS_INF }
then
Result := DWORD(-1)
{ failed, GetLastError has error code }
else begin
Waitfor(ProcessInfo.hProcess);
GetExitCodeProcess(ProcessInfo.hProcess, Result);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
end;
{ Else }
end;
{ WinExecAndWait32V2 }