views:

205

answers:

1

I have some code that starts a process and hooks up an event handler to handle when the process exits, the code I have is written in C# and I wonder if something similar is possible with Delphi.

System.Diagnostics.Process myProcess = new System.Diagnostics.Process();
myProcess.StartInfo.FileName = "notepad.exe";
myProcess.EnableRaisingEvents = true;
myProcess.Exited += new System.EventHandler(Process_OnExit);
myProcess.Start();

public void Process_OnExit(object sender, EventArgs e)
{
    //Do something when the process ends
}

I don't know much about Delphi so any help would be appreciated, thanks.

+5  A: 

Yes, you can do something similar with Delphi. I have not seen using an event handler, but you can create a process, wait for it to finish, and then do something when that happens. Put it in another thread if you want to do something in the mean time.

Here is some code for creating a process and waiting that I scraped off the net:

procedure ExecNewProcess(ProgramName : String; Wait: Boolean);
var
  StartInfo : TStartupInfo;
  ProcInfo : TProcessInformation;
  CreateOK : Boolean;
begin
    { fill with known state } 
  FillChar(StartInfo,SizeOf(TStartupInfo), 0);
  FillChar(ProcInfo,SizeOf(TProcessInformation), 0);
  StartInfo.cb := SizeOf(TStartupInfo);
  CreateOK := CreateProcess(nil, PChar(ProgramName), nil, nil,False,
              CREATE_NEW_PROCESS_GROUP or NORMAL_PRIORITY_CLASS,
              nil, nil, StartInfo, ProcInfo);
    { check to see if successful } 
  if CreateOK then
    begin
        //may or may not be needed. Usually wait for child processes 
      if Wait then
        WaitForSingleObject(ProcInfo.hProcess, INFINITE);
    end
  else
    begin
      //ShowMessage('Unable to run '+ProgramName);
      SysErrorMessage(GetLastError());
    end;

  CloseHandle(ProcInfo.hProcess);
  CloseHandle(ProcInfo.hThread);
end;
Jim McKeeth
I would not use INFINITE but a timeout and a loop to be able to interrupt the wait if needed, or WaitForMultipleObject() with an event to exit the wait. Otherwise it could be impossible to terminate the waiting thread cleanly.Also if CreateProcess() fails, don't hide the error emitting a generic, useless message, but call RaiseLasOSError to show the real error.
ldsandon
Another hint: FilLChar last parameter does not need to be a char - it could be a byte. To avoid Unicode issues, if you're just filling a binary struct with zeroes, pass 0, not #0.
ldsandon
Both good advice @ldsandon. I have done both in production code.
Jim McKeeth
@Jim: When combining bits in flags, you should always use OR instead of +. You're operating at the bit-flag level, and addition may give you different results than a binary OR.
Ken White