Terminate a process tree (C for Windows)

wonderer picture wonderer · Jul 23, 2009 · Viewed 23.2k times · Source

This has been asked before but I can't find a definitive answer, in code.

I open a process, ProcessA (with PID 1234). This process opens a child process, ProcessAB (PID 5678). After I'm done I terminate ProcessA but I still have the lingering of ProcessAB.

How do I terminate the whole process tree? What I mean, how do I make sure that if I terminate the process I opened I am also terminating all the associated processes?

Thanks

Code is appreciated.

Answer

Mike Marshall picture Mike Marshall · Jul 23, 2009

Check this thread for grouping processes within a "job".

If that does not work for you, a home grown approach might go as follows:

  1. Get your main process ID
  2. Call CreateToolhelp32Snapshot to enumerateall the processes on the system
  3. Check the th32ParentProcessID member of the PROCESSENTRY32 structure on each process, if it matches your parent ID, then terminate the process (using TerminateProcess)
  4. After all children are terminated, terminate the main process

Sample code:

    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);
    }       
}