Skip to content

Instantly share code, notes, and snippets.

@lostmsu
Created May 20, 2022 17:53
Show Gist options
  • Save lostmsu/a806fbfedf7a3dba184c4e3d38dc5110 to your computer and use it in GitHub Desktop.
Save lostmsu/a806fbfedf7a3dba184c4e3d38dc5110 to your computer and use it in GitHub Desktop.
make child process terminate automatically when the current process terminates
using System;
using System.Runtime.InteropServices;
using static PInvoke.Kernel32;
// usage: new Job().AddProcess(new SafeObjectHandle(win32childProcessHandle, ownsHandle: false);
// might need to keep Job instance alive
public class Job : IDisposable
{
readonly SafeObjectHandle handle;
public Job() {
this.handle = CreateJobObject(IntPtr.Zero, null);
var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION {
LimitFlags = JOB_OBJECT_LIMIT_FLAGS.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE,
};
var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION {BasicLimitInformation = info};
int length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length);
Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);
if (!SetInformationJobObject(this.handle, JOBOBJECTINFOCLASS.JobObjectExtendedLimitInformation, extendedInfoPtr, (uint)length))
throw new System.ComponentModel.Win32Exception();
}
public bool AddProcess(SafeObjectHandle processHandle) {
return AssignProcessToJobObject(this.handle, processHandle);
}
#region IDisposable Members
public void Dispose() {
this.Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing) => this.Close();
public void Close() => this.handle.Close();
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment