ichen
asked on
GetExitCodeProcess
How can i create a timer for my application to call GetExitCodeProcess() . If the function returns 0
and the lpExitCode is STILL_ACTIVE , the program has not yet been terminated . If the function returns true , then the lpExitCode has the returned error value ( errorlevel ) ,
Can anyone help me.. i need a source please..!! THANKS
and the lpExitCode is STILL_ACTIVE , the program has not yet been terminated . If the function returns true , then the lpExitCode has the returned error value ( errorlevel ) ,
Can anyone help me.. i need a source please..!! THANKS
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
you whipped good John :-), Zif.
ZifNab's answer is the way to do it. Just execute his code in a thread so that your main app doesn't lock.
If you still want to do it the timer way; here's an example I just whipped together:
type
TProcessWatch = class( TTimer )
private
FhProcess : THandle;
FiExitCode: Integer;
FbRunning : Boolean;
FOnExit : TNotifyEvent;
procedure FWatch(Sender: TObject);
property OnTimer;
public
constructor Create( AOwner: TComponent; Process: THandle; Suspended: Boolean );
procedure Start;
procedure Stop;
property Handle : THandle read FhProcess write FhProcess;
property ExitCode: Integer read FiExitCode;
property Running : Boolean read FbRunning;
property OnProcessExit: TNotifyEvent read FOnExit write FOnExit;
end;
.
procedure TProcessWatch.FWatch(Sende
var
iExitCode: Integer;
begin
if ( GetExitCodeProcess( FhProcess, iExitCode ) )
then begin
FiExitCode := iExitCode;
FbRunning := ( iExitCode = STILL_ACTIVE );
if ( not FbRunning ) and Assigned( FOnExit )
then FOnExit( Self );
end else begin
FiExitCode := -1;
FbRunning := False;
end;
end;
constructor TProcessWatch.Create( AOwner: TComponent; Process: THandle; Suspended: Boolean );
begin
inherited Create( AOwner );
inherited OnTimer := FWatch;
FhProcess := Process;
OnTimer( Self ); // get initial status
Enabled := not Suspended;
end;
procedure TProcessWatch.Start;
begin
Enabled := True;
end;
procedure TProcessWatch.Stop;
begin
Enabled := False;
end;
To use it:
procedure TForm1.OnExitProc(Sender: TObject);
begin
Windows.Beep( 1000, 1000 );
( Sender as TProcessWatch ).Free;
end;
.
procedure TForm1.NotepadButtonClick(
var
Command : string;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
begin
Command := 'notepad';
FillChar(StartupInfo, Sizeof(StartupInfo),#0);
StartupInfo.cb := SizeOf( StartupInfo );
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := SW_SHOWNORMAL;
if CreateProcess(nil,
PChar(Command), { 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 begin
with TProcessWatch.Create( Self, ProcessInfo.hProcess, True ) do begin // create suspended
OnProcessExit := OnExitProc;
Interval := 100; // faster check than def
Start;
end;
end;
end;
Not pretty, but working!
/// John