function ExecuteExe(
const Executable:
String; Commands:
String;
const ShowConsole, DoWait: Boolean): Cardinal;
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
while PeekMessage(Msg, 0, WM_PAINT, WM_PAINT, PM_REMOVE)
do
DispatchMessage(Msg);
end;
until ret = WAIT_OBJECT_0;
end;
{ Waitfor }
var
Security : TSecurityAttributes;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
begin
Result := Cardinal($FFFFFFFF);
if ((Length(Commands) > 1)
and (Commands[1]<>'
'))
then
Commands := '
' + Commands;
with Security
do begin
nLength := SizeOf(TSecurityAttributes);
lpSecurityDescriptor :=
nil;
bInheritHandle := False;
end;
FillChar(StartupInfo, SizeOf(StartupInfo), #0);
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW
or STARTF_FORCEONFEEDBACK;
if ShowConsole
then StartupInfo.wShowWindow := SW_SHOWNORMAL
else StartupInfo.wShowWindow := SW_HIDE;
if CreateProcess(PChar(Executable), PChar(Commands), @Security, @Security, False, CREATE_NEW_CONSOLE
or NORMAL_PRIORITY_CLASS,
nil, PChar(ExtractFilePath(Executable)), StartupInfo, ProcessInfo)
then
begin
if DoWait
then WaitFor(ProcessInfo.hProcess);
if not GetExitCodeProcess(ProcessInfo.hProcess, Result)
then Result := Cardinal($FFFFFFFF);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
end
else
Result := GetLastError;
end;