Pregunta

Esto se ha hecho antes, pero no puedo encontrar una respuesta definitiva, en el código.

I abrir un proceso, Processa (con PID 1234). Este proceso abre un proceso hijo, ProcessAB (PID 5678). Después he terminado por terminado Processa pero todavía tengo el persistente de ProcessAB.

¿Cómo termino todo el árbol de procesos? Lo que quiero decir, ¿cómo me aseguro de que si terminar el proceso abrí También estoy de terminación todos los procesos asociados?

Gracias

Código es apreciado.

¿Fue útil?

Solución

este hilo para los procesos de agrupación dentro de un "trabajo".

Si eso no funciona para usted, un enfoque crecido el hogar podría ser la siguiente:

  1. Obtener su ID de proceso principal
  2. CreateToolhelp32Snapshot a enumerateall los procesos en el sistema
  3. Compruebe el miembro de th32ParentProcessID de la estructura PROCESSENTRY32 en cada proceso, si coincide con su nombre de los padres, y luego terminar el proceso (usando TerminateProcess )
  4. Después de que todos los niños se terminan, dar por terminado el proceso principal

Código de ejemplo:

    DWORD myprocID = 1234; // your main process id

PROCESSENTRY32 pe;

memset(&pe, 0, sizeof(PROCESSENTRY32));
pe.dwSize = sizeof(PROCESSENTRY32);

HANDLE hSnap = :: CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if (::Process32First(hSnap, &pe))
{
    BOOL bContinue = TRUE;

    // kill child processes
    while (bContinue)
    {
        // only kill child processes
        if (pe.th32ParentProcessID == myprocID)
        {
            HANDLE hChildProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);

            if (hChildProc)
            {
                ::TerminateProcess(hChildProc, 1);
                ::CloseHandle(hChildProc);
            }               
        }

        bContinue = ::Process32Next(hSnap, &pe);
    }

    // kill the main process
    HANDLE hProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, myprocID);

    if (hProc)
    {
        ::TerminateProcess(hProc, 1);
        ::CloseHandle(hProc);
    }       
}

Otros consejos

Objetos

Trabajo .

Es lo más parecido a un UNIX 'grupo de procesos' que Windows tiene que ofrecer.

Los objetos de trabajo le permiten indicar un proceso hijo (y todos sus hijos) pueden ser administrados juntos, esp. para ser asesinados. A diferencia de Unix, como de este escrito 'objetos de trabajo' no pueden anidarse . Lo que significa que si un padre crea un objeto de trabajo para un niño, todos los niños de ese niño no pueden ellos mismos usan objetos de trabajo (que es un / grave en mi humilde opinión / limitación, como un sistema de archivos que sólo permite un nivel de subdirectorios).

Para matar a un árbol entero con TODO !!! childs:

bool __fastcall KillProcessTree(DWORD myprocID, DWORD dwTimeout)
{
  bool bRet = true;
  HANDLE hWnd;
  PROCESSENTRY32 pe;

  memset(&pe, 0, sizeof(PROCESSENTRY32));
  pe.dwSize = sizeof(PROCESSENTRY32);

  HANDLE hSnap = :: CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

  if (::Process32First(hSnap, &pe))
  {
    BOOL bContinue = TRUE;

    // kill child processes
    while (bContinue)
    {
      if (pe.th32ParentProcessID == myprocID)
      {
        ShowMessage ("Gleich - KILL PID: " + AnsiString(pe.th32ProcessID));

        // Rekursion
        KillProcessTree(pe.th32ProcessID, dwTimeout);

        HANDLE hChildProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);

        if (hChildProc)
        {
          GetWindowThreadProcessId(hWnd, &myprocID);
          // CLOSE Message s
          PostMessage(hWnd, WM_CLOSE, 0, 0) ;

          if (WaitForSingleObject(hChildProc, dwTimeout) == WAIT_OBJECT_0)
            bRet = true;
          else
          {
            bRet = TerminateProcess(hChildProc, 0);
          }
          ::CloseHandle(hChildProc);
        }
      }
      bContinue = ::Process32Next(hSnap, &pe);
    }

    // kill the main process
    HANDLE hProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, myprocID);

    if (hProc)
    {
        ::TerminateProcess(hProc, 1);
        ::CloseHandle(hProc);
    }
  }
  return bRet;
}

Hay Cómo matar a un el árbol de procesos, pero es en C #. No creo que sea demasiado difícil de puerto que a C.

NtQueryInformationProcess Función y < a href = "http://msdn.microsoft.com/en-us/library/ms686714%28VS.85%29.aspx" rel = "nofollow noreferrer"> TerminateProcess Función .

@mjmarsh responde a las necesidades recursividad para el caso homebrew, de lo contrario es la correcta. Creación de objetos de trabajo es mejor que la de abajo cuando pueda.

void KillProcessTree(DWORD myprocID)
{
    PROCESSENTRY32 pe;

    memset(&pe, 0, sizeof(PROCESSENTRY32));
    pe.dwSize = sizeof(PROCESSENTRY32);

    HANDLE hSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if (::Process32First(hSnap, &pe))
    {
        do // Recursion
        {
            if (pe.th32ParentProcessID == myprocID)
                KillProcessTree(pe.th32ProcessID);
        } while (::Process32Next(hSnap, &pe));
    }


    // kill the main process
    HANDLE hProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, myprocID);

    if (hProc)
    {
        ::TerminateProcess(hProc, 1);
        ::CloseHandle(hProc);
    }
}

La siguiente es para Linux, pero espero que ayude para Windows con algunas adaptaciones.

Cuando fork (), salvo el valor de retorno, que es el pid del proceso hijo, entonces cuando el padre está a punto de salir, matar () el pid.

Si tiene varios procesos secundarios, puede enviar la matanza al grupo de procesos. Por defecto, los procesos hijos tienen el mismo pgid como padre.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top