Вам необходимо использовать jobs. Основной исполняемый файл должен быть create a job object, тогда вам нужно указать set флаг 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;
Затем нужно выполнить другой процесс с 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;
Когда все это выполнено, все дочерние процессы будут автоматически завершены, даже если основной исполняемый файл был убит. Вы можете получить блок JobsApi here. Примечание. Я не тестировал его с помощью Delphi 7.
EDIT: Here вы можете скачать рабочий демонстрационный проект.
Получить главный исполняемый файл, чтобы отправить сообщение для дочернего исполняемого файла, когда основной исполняемый закрывается. –
не тогда, когда главный исполняемый файл убит – ZigiZ
Работа представляется изящным решением. Кроме того, вы можете наследовать дескриптор родительского процесса и ждать, пока он будет передан по завершении. – OnTheFly