2009-03-02 11 views
12

Tenemos un C++ tarea que desembolsar un nuevo proceso. Ese proceso a su vez puede tener varios procesos secundarios. Si la tarea se ejecuta más allá de un tiempo asignado, querremos matar ese proceso bifurcado. Sin embargo, no queremos huérfanos de los procesos generados. Queremos que todos mueran. He usado Process Explorer y tiene una opción "Kill Process Tree", similar al "End Process Tree" del Administrador de tareas de Windows, así que supongo/supongo que hay una API pública para hacer esto. ¿Alguien ha hecho esto o sabe de una referencia a una API pública que sí lo hace?Realización equivalente de "Kill Process árbol" en C++ en ventanas

Thx, Brett

+0

Creo que el Administrador de tareas hace una variedad de cosas que no están disponibles a través de API públicas. – jdigital

+0

aunque no tendría ningún problema para creerlo;) el hecho de que Process Explorer lo haga me hace pensar. Creo que fue escrito antes de que esa compañía fuera adquirida mi MS. –

+0

Sí, pero el tipo que escribió el explorador de procesos - Mark Russinovich - solía trabajar para Microsoft en Windows NT (antes de comprar su empresa con Microsoft) y literariamente escribió el libro sobre el funcionamiento interno de Windows. http://www.microsoft.com/learning/en/us/books/12069.aspx –

Respuesta

18

Es posible que desee considerar la "API de trabajos". CreateJobObject y amigos. Puede aplicar procesos secundarios para permanecer dentro del Trabajo, configurando el atributo apropiado. Luego puede llamar a TerminateJobObject cuando lo desee.

Aclaración: esto no lo hace el Administrador de tareas es.

+1

seguimiento, si ese proceso bifurcado muere y deja huérfanos sus trabajos, ¿terminaráJobObject podrá matar a los huérfanos que quedan? –

+2

Sí, consulte el documento relevante de la API. A menos que se haya creado un proceso con el indicador CREATE_BREAKAWAY_FROM_JOB. – EFraim

+2

Aunque no se puede ejecutar si no se establece el límite JOB_OBJECT_LIMIT_BREAKAWAY_OK en el objeto de trabajo. – EFraim

4

hay una función llamada Win32 TerminateProcess(). Debería hacer el trabajo por ti.

Alternativamente, he encontrado el comando taskkill sea útil para cosas como esta.

desde la línea de comandos:

taskkill /F /T /IM program.exe 

de código:

system("taskkill /F /T /IM program.exe"); 

otros interruptores (directamente desde taskkill /?):

 TASKKILL [/S system [/U username [/P 
[password]]]] 
      { [/FI filter] [/PID processid | /IM imagename] } [/F] [/T] 

Description: 
    This command line tool can be used to end one or more processes. 
    Processes can be killed by the process id or image name. 

Parameter List: 
    /S system   Specifies the remote system to connect to. 

    /U [domain\]user Specifies the user context under which 
          the command should execute. 

    /P [password]  Specifies the password for the given 
          user context. Prompts for input if omitted. 

    /F      Specifies to forcefully terminate 
          process(es). 

    /FI filter   Displays a set of tasks that match a 
          given criteria specified by the filter. 

    /PID process id  Specifies the PID of the process that 
          has to be terminated. 

    /IM image name  Specifies the image name of the process 
          that has to be terminated. Wildcard '*' 
          can be used to specify all image names. 

    /T      Tree kill: terminates the specified process 
          and any child processes which were started by it. 

    /?      Displays this help/usage.

-John

+5

TerminateProcess no mata automáticamente todos los procesos secundarios. – Cray

1

Desea encontrar la identificación del proceso para el proceso que desea matar, luego "caminar por el árbol" de sus hijos (y sus hijos, y así sucesivamente ...), anote sus pides, y luego mata todos los procesos agradable y rápido.

6

le sugiero ir la ruta objeto de trabajo, como se indicó anteriormente, será la más fiable. Si no puede ir a la ruta del objeto de trabajo, puede usar la API de ayuda de herramientas para obtener ID de proceso padre y construir el árbol de esa manera. Tenga cuidado, ya que Windows no tiene una fuerte relación padre/hijo y es posible que los PID se reciclen. Puede utilizar GetProcessTimes para consultar la hora de creación del proceso y verificar que sea anterior al hijo. Si se termina un proceso intermedio en el árbol, no podrás caminar más lejos.

// Error handling removed for brevity 
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
PROCESSENTRY32 process; 
ZeroMemory(&process, sizeof(process)); 
process.dwSize = sizeof(process); 
Process32First(snapshot, &process); 
do 
{ 
    // process.th32ProcessId is the PID. 
    // process.th32ParentProcessID is the parent PID. 

} while (Process32Next(snapshot, &process)); 
+1

Sí, esto es lo que necesitarás usar en Vista. –

+0

Lo necesitarás en XP también. – bltxd