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?
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.
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));
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
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.
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