5
votes

The MSDN page on Job Objects explains:

A process can be associated with only one job. Jobs cannot be nested. The ability to nest jobs was added in Windows 8 Consumer Preview and Windows Server 8 Beta.

Unfortunately, it seems that this is just what I need. I'm dealing with a process tree like this:

server.exe
  |
  +--+ utility.exe
  |
  +--+ launcherA.exe
  |      |
  |      +--+ programA.exe
  |             |
  |             +--+ subProcessA.exe
  |
  +--+ launcherB.exe
         |
         +--+ programB.exe

I try to implement the following behaviour:

  1. If server.exe gets terminated somehow (because it crashes, or because the user decides to terminate it using the task manager, or simply because it finishes executing), it takes down all processes beneath it. I use a job object for this.

  2. If launcherA.exe or launchedB.exe terminate for some reason, they take down all processes beneath them. Unfortunately I cannot use job objects here since job objects don't nest.

As it is, I often manage to create 'dangling' processes by killing arbitrary processes in the above tree. I try to avoid leaving any stale processes behind, but all solutions I've come up with so far rely on some sort of watchdog process which monitors other processes - but if the watchdog itself gets killed, all hope is lost.

1
Keep the top-level job on server.exe, and make server.exe be the watchdog. That way, if the watchdog dies, the job object will take down all the subprocesses. - Raymond Chen
@RaymondChen: Sounds good. If I make server.exe watch launcherA.exeand launchedB.exe, I do notice when they get terminated for some reason. However - how can I figure out the child processes at that point? I'm using WaitForSingleObject to get notified about the process end, but at that time I cannot tell what the child processes are because they have already been reparented. I did consider CreateToolhelp32Snapshot to keep track of child processes, or maybe WMI. Is there maybe an easier solution? - Frerich Raabe
You said you had a solution with watchdog processes. Just reuse that solution (including the part that keeps track of the subprocesses), but make server.exe be the watchdog. - Raymond Chen
@RaymondChen: The issue is that my watchdogs always only manage to track one level of processes (direct descendants of themselves). If server.exe is the watchdog, I'd need to come up with a way to determine e.g. all processes beneath launcherA.exe after launcherA.exe terminated. Taking process snapshots probably introduces race conditions, so the only solutions I can think of right now is hooking the NtCreateProcess API or using WMI to get notified of process creations. I wonder whether there's something else. - Frerich Raabe
You can use Process32First to get the parent process ID. Feel free to write up your solution and accept it. - Raymond Chen

1 Answers

0
votes

I think there are misunderstanding what is the new feature Nested Jobs which will be supported in Windows 8.

If you use start process server.exe which starts process launcherA.exe which start process subProcessA.exe and so on you need just start server.exe in a job. In the way all other children (launcherA.exe, subProcessA.exe and so on) will be started automatically inside of the same job as his parent. So you can monitor all collection of the processes at once. You can even receive notification on every start of new process to create detailed log file for example. I did this on some applications and it works very good.

The only problem which you can receive is if some from the child exe are also "modern enough" and use Jobs to control his children. Only in the case you would have to use new Nested Jobs.

If I understood correct your question your current problem can be simple solved by placing server.exe only in a new job.