Search code examples
cwindowsprocessterminate

Terminate a process tree (C for Windows)


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.


Solution

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