Performing equivalent of “Kill Process Tree” in C+

2020-02-05 03:47发布

问题:

We have a C++ task that will fork a new process. That process in turn may have several child processes. If the task runs past an allotted time, we will want to kill that forked process.

However, we don't want to orphan the processes it has spawned. We want them all to die. I have used Process Explorer and it has a "Kill Process Tree" option, similar to Windows Task Manager's "End Process Tree", so I'm guessing/assuming there is a public API to do this. Has anyone done this, or know of a reference to a public API that does?

回答1:

You might want to consider the "Jobs API". CreateJobObject and friends. You can enforce children processes to stay within the Job, by setting appropriate attribute. Then you can call TerminateJobObject whenever you want.

Clarification: this is NOT what Task Manager does.



回答2:

I suggest going the job object route, as indicated above, it will be the most reliable.

If you can't go the job object route, you can use the toolhelp API to get parent process ID's and build the tree that way. Be cautious though, since Windows doesn't have a strong parent/child relationship and it is possible for PID's to get recycled. You can use GetProcessTimes to query the creation time of the process, and check that it is older than the child. If an intermediate process in the tree is terminated, you will not be able to walk the tree further.

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


回答3:

There is a Win32 function called TerminateProcess(). It should do the job for you.

Alternatively, I've found the taskkill command to be useful for things like this.

from the command line:

taskkill /F /T /IM program.exe

from code:

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

other switches (straight from 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



回答4:

You want to find the process id for the process you want to kill, then "walk the tree" of its children (and their children, and so on...), note their pids, and then kill all the processes nice and quickly.



回答5:

You can also use WMI, route planning you can create a class to perform the tasks.
Se this "Where can I find the WMI documentation?"
and The WMI COM library
and WMI C++ Application Examples



标签: c++ windows kill