There is a recommendation to associate a Job Object with I/O completion port and to listen for notifications JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO
as a right way to wait for child process (without access to source code) tree completion. But in MSDN:
Note that, except for limits set with the JobObjectNotificationLimitInformation information class, messages are intended only as notifications and their delivery to the completion port is not guaranteed. The failure of a message to arrive at the completion port does not necessarily mean that the event did not occur.
So there is no really reliable way to wait for the process tree completion in Windows, isn't it?
I played abit with the other options that exist and using the I/O completion port is the only available method besides WaitForObject, WaitForObjectEx and the pendant for multiple objects.
More interestingly though, at least on Windows 10, TerminateJobObject is not applied unless aforementioned methods are being called.
To that regard, QueryInformationJobObject with for example JOBOBJECT_BASIC_ACCOUNTING_INFORMATION will show that the processes in the job object are not terminated.
So to be reliable, you have to