private void UpdateExtendedLimit() { NativeMethods.JOBOBJECT_EXTENDED_LIMIT_INFORMATION extendedLimit = new NativeMethods.JOBOBJECT_EXTENDED_LIMIT_INFORMATION(); NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION basicLimit = new NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION(); basicLimit.LimitFlags = 0; if (this.killProcessesOnJobClose) { basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; } if (this.dieOnUnhandledException) { basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION; } if (this.allowChildProcessesBreakaway) { basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_BREAKAWAY_OK; } if (this.alwaysBreakawayChildProcesses) { basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK; } if (this.activeProcessesLimit != 0) { basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_ACTIVE_PROCESS; basicLimit.ActiveProcessLimit = this.activeProcessesLimit; } if (this.processMemoryLimit != 0) { basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_PROCESS_MEMORY; extendedLimit.ProcessMemoryLimit = (IntPtr)this.processMemoryLimit; } if (this.jobMemoryLimit != 0) { basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_JOB_MEMORY; extendedLimit.JobMemoryLimit = (IntPtr)this.jobMemoryLimit; } if (this.processUserTimeLimit != 0) { basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_PROCESS_TIME; basicLimit.PerProcessUserTimeLimit = this.processUserTimeLimit; } if (this.jobUserTimeLimit != 0) { if (this.jobUserTimeLimitChanged) { basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_JOB_TIME; basicLimit.PerJobUserTimeLimit = this.jobUserTimeLimit; this.jobUserTimeLimitChanged = false; } else { basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME; } } if (this.priorityClass != 0) { basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_PRIORITY_CLASS; basicLimit.PriorityClass = this.priorityClass; } if (this.schedulingClass != 0) { basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_SCHEDULING_CLASS; basicLimit.SchedulingClass = this.schedulingClass; } if (this.affinity != IntPtr.Zero) { basicLimit.LimitFlags |= NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION.JOB_OBJECT_LIMIT_AFFINITY; basicLimit.Affinity = this.affinity; } extendedLimit.BasicLimitInformation = basicLimit; int extendedLimitLength = Marshal.SizeOf(typeof(NativeMethods.JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); IntPtr extendedLimitPtr = Marshal.AllocHGlobal(extendedLimitLength); try { Marshal.StructureToPtr(extendedLimit, extendedLimitPtr, false); bool success = NativeMethods.SetInformationJobObject(this.jobHandle, NativeMethods.JobObjectInfoClass.JobObjectExtendedLimitInformation, extendedLimitPtr, (uint)extendedLimitLength); if (success == false) { int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error, "SetInformationJobObject failed."); } } finally { Marshal.FreeHGlobal(extendedLimitPtr); } }