static ChildProcessTracker() { // This feature requires Windows 8 or later. To support Windows 7 requires // registry settings to be added if you are using Visual Studio plus an // app.manifest change. // http://stackoverflow.com/a/4232259/386091 // http://stackoverflow.com/a/9507862/386091 if (Environment.OSVersion.Version < new Version(6, 2)) return; // The job name is optional (and can be null) but it helps with diagnostics. // If it's not null, it has to be unique. Use SysInternals' Handle command-line // utility: handle -a ChildProcessTracker var jobName = "ChildProcessTracker" + Process.GetCurrentProcess().Id; _jobHandle = CreateJobObject(IntPtr.Zero, jobName); var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION { // This is the key flag. When our process is killed, Windows will automatically // close the job handle, and when that happens, we want the child processes to // be killed, too. LimitFlags = JOBOBJECTLIMIT.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE }; var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION { BasicLimitInformation = info }; var length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); var extendedInfoPtr = Marshal.AllocHGlobal(length); try { Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false); if (!SetInformationJobObject(_jobHandle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length)) { throw new Win32Exception(); } } finally { Marshal.FreeHGlobal(extendedInfoPtr); } }
static ChildProcessTracker() { // This feature requires Windows 8 or later. To support Windows 7 requires // registry settings to be added if you are using Visual Studio plus an // app.manifest change. // http://stackoverflow.com/a/4232259/386091 // http://stackoverflow.com/a/9507862/386091 if (Environment.OSVersion.Version < new Version(6, 2)) { return; } // The job name is optional (and can be null) but it helps with diagnostics. // If it's not null, it has to be unique. Use SysInternals' Handle command-line // utility: handle -a ChildProcessTracker var jobName = "ChildProcessTracker" + Process.GetCurrentProcess().Id; _jobHandle = CreateJobObject(IntPtr.Zero, jobName); var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION { // This is the key flag. When our process is killed, Windows will automatically // close the job handle, and when that happens, we want the child processes to // be killed, too. LimitFlags = JOBOBJECTLIMIT.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE }; var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION { BasicLimitInformation = info }; var length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); var extendedInfoPtr = Marshal.AllocHGlobal(length); try { Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false); if (!SetInformationJobObject(_jobHandle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length)) { throw new Win32Exception(); } } finally { Marshal.FreeHGlobal(extendedInfoPtr); } }