private static void ConfigureJob(SafeWaitHandle Job)
{
JOBOBJECT_EXTENDED_LIMIT_INFORMATION ExtendedLimit;
ExtendedLimit.BasicLimitInformation.PerProcessUserTimeLimit = 0;
ExtendedLimit.BasicLimitInformation.PerJobUserTimeLimit = 0;
ExtendedLimit.BasicLimitInformation.LimitFlags = 0;
ExtendedLimit.BasicLimitInformation.MinimumWorkingSetSize = UIntPtr.Zero;
ExtendedLimit.BasicLimitInformation.MaximumWorkingSetSize = UIntPtr.Zero;
ExtendedLimit.BasicLimitInformation.ActiveProcessLimit = 0;
ExtendedLimit.BasicLimitInformation.Affinity = UIntPtr.Zero;
ExtendedLimit.BasicLimitInformation.PriorityClass = 0;
ExtendedLimit.BasicLimitInformation.SchedulingClass = 0;
ExtendedLimit.IoInfo.ReadOperationCount = 0;
ExtendedLimit.IoInfo.WriteOperationCount = 0;
ExtendedLimit.IoInfo.OtherOperationCount = 0;
ExtendedLimit.IoInfo.ReadTransferCount = 0;
ExtendedLimit.IoInfo.WriteTransferCount = 0;
ExtendedLimit.IoInfo.OtherTransferCount = 0;
ExtendedLimit.ProcessMemoryLimit = UIntPtr.Zero;
ExtendedLimit.JobMemoryLimit = UIntPtr.Zero;
ExtendedLimit.PeakProcessMemoryUsed = UIntPtr.Zero;
ExtendedLimit.PeakJobMemoryUsed = UIntPtr.Zero;
//
// Set the job to terminate all contained processes on last handle
// close (for the job itself), and to terminate all processes that
// are in the job and which have an unhandled exception in lieu of
// blocking them on the hard error dialog box.
//
ExtendedLimit.BasicLimitInformation.LimitFlags = JOBOBJECTLIMIT.KillOnJobClose | JOBOBJECTLIMIT.DieOnUnhandledException;
int LimitSize = Marshal.SizeOf(ExtendedLimit);
IntPtr JobInformation = Marshal.AllocHGlobal(LimitSize);
try
{
Marshal.StructureToPtr(ExtendedLimit, JobInformation, false);
if (SetInformationJobObject(Job.DangerousGetHandle(),
JOBOBJECTINFOCLASS.ExtendedLimitInformation,
JobInformation,
(uint)LimitSize) == 0)
{
throw new ApplicationException("SetInformationJobObject failed: " + Marshal.GetLastWin32Error());
}
}
finally
{
Marshal.FreeHGlobal(JobInformation);
}
}