La API de Windows admite objetos denominados "Objetos de trabajo". El siguiente código creará un "trabajo" que está configurado para cerrar todos los procesos cuando finaliza la aplicación principal (cuando se limpian sus identificadores). Este código sólo se debe ejecutar una vez .:
HANDLE ghJob = CreateJobObject(NULL, NULL); // GLOBAL
if(ghJob == NULL)
{
::MessageBox(0, "Could not create job object", "TEST", MB_OK);
}
else
{
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 };
// Configure all child processes associated with the job to terminate when the
jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
if(0 == SetInformationJobObject(ghJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)))
{
::MessageBox(0, "Could not SetInformationJobObject", "TEST", MB_OK);
}
}
Luego, cuando se crea cada proceso hijo, ejecute el siguiente código para poner en marcha cada niño cada proceso y añadirlo al objeto de trabajo:
STARTUPINFO info={sizeof(info)};
PROCESS_INFORMATION processInfo;
// Launch child process - example is notepad.exe
if (::CreateProcess(NULL, "notepad.exe", NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo))
{
::MessageBox(0, "CreateProcess succeeded.", "TEST", MB_OK);
if(ghJob)
{
if(0 == AssignProcessToJobObject(ghJob, processInfo.hProcess))
{
::MessageBox(0, "Could not AssignProcessToObject", "TEST", MB_OK);
}
}
// Can we free handles now? Not sure about this.
//CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}
VISTA NOTA: Consulte AssignProcessToJobObject always return "access denied" on Vista si encuentra problemas de acceso denegado con AssignProcessToObject() en vista.
Para responder a su pregunta en el comentario: Sí, debe cerrar Close cuando ya no necesite el identificador. –
Sí, ¿pero terminará así el trabajo? –
No, no lo creo. JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE hace que el trabajo finalice cuando se cierre el último identificador * job *, los identificadores de proceso no deberían marcar la diferencia. ¿Lo has probado? –