如何创建一个Child进程取决于它的父进程?

Zig*_*giZ 8 delphi delphi-7

我的应用程序(main.exe)正在执行子进程(child.exe)使用ShellExecuteEx.

但是当我关闭或杀死(通过Process-Explorer)main.exe时,子进程仍然处于活动状态.

main.exe终止child.exe终止时,如何优雅地处理它?

Lin*_*nas 13

你需要使用工作.主可执行文件应该创建一个作业对象,然后您需要 JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE标志设置为您的作业对象.

uses
  JobsApi;
//...
var
  jLimit: TJobObjectExtendedLimitInformation;

  hJob := CreateJobObject(nil, PChar('JobName');
  if hJob <> 0 then
  begin
    jLimit.BasicLimitInformation.LimitFlags := JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
      SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, @jLimit,
        SizeOf(TJobObjectExtendedLimitInformation));
  end; 
Run Code Online (Sandbox Code Playgroud)

然后,您需要使用CreateProcess函数执行另一个进程,其中dwCreationFlags必须设置为CREATE_BREAKAWAY_FROM_JOB.如果此功能成功通话AssignProcessToJobObject.

function ExecuteProcess(const EXE : String; const AParams: string = ''; AJob: Boolean = True): THandle;
var
  SI : TStartupInfo;
  PI : TProcessInformation;
  AFlag: Cardinal;
begin
  Result := INVALID_HANDLE_VALUE;
  FillChar(SI,SizeOf(SI),0);
  SI.cb := SizeOf(SI);

  if AJob then
    AFlag := CREATE_BREAKAWAY_FROM_JOB
  else
    AFlag := 0;


  if CreateProcess(
     nil,
     PChar(EXE + ' ' + AParams),
     nil,
     nil,
     False,
     AFlag,
     nil,
     nil,
     SI,
     PI
     ) then
  begin
   { close thread handle }
    CloseHandle(PI.hThread);
    Result := PI.hProcess;
  end;
end;
//...
  hApp := ExecuteProcess('PathToExecutable');

  if hApp <> INVALID_HANDLE_VALUE then
  begin
     AssignProcessToJobObject(hJob, hApp);
  end;
Run Code Online (Sandbox Code Playgroud)

完成所有这些操作后,即使主可执行文件已被终止,所有子进程也将自动终止.你可以在这里获得JobsApi单元.注意:我没有使用Delphi 7进行测试.

编辑:在这里你可以下载工作演示项目.

  • 你不会相信,如果我告诉你是什么导致这个:[Process Explorer](http://forum.sysinternals.com/bug-job-Object-limit-kill-On-jobclose_topic4094.html).是责怪的!:-P (2认同)