Created
November 11, 2018 04:52
-
-
Save TIHan/cd37aed3598c11dc50b97c2cdcb45c84 to your computer and use it in GitHub Desktop.
F# Process - Kill Child when Parent Dies
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// https://stackoverflow.com/questions/3342941/kill-child-process-when-parent-process-is-killed | |
module WindowsHelpers = | |
open System.Runtime.InteropServices | |
open FSharp.NativeInterop | |
type JobObjectInfoType = | |
| AssociateCompletionPortInformation = 7 | |
| BasicLimitInformation = 2 | |
| BasicUIRestrictions = 4 | |
| EndOfJobTimeInformation = 6 | |
| ExtendedLimitInformation = 9 | |
| SecurityLimitInformation = 5 | |
| GroupInformation = 11 | |
[<Struct>] | |
type SECURITY_ATTRIBUTES = | |
val mutable nLength : int | |
val mutable lpSecurityDescriptor : IntPtr | |
val mutable bInheritHandle : int | |
[<Struct>] | |
type IO_COUNTERS = | |
val mutable ReadOperationCount : uint64 | |
val mutable WriteOperationCount : uint64 | |
val mutable OtherOperationCount : uint64 | |
val mutable ReadTransferCount : uint64 | |
val mutable WriteTransferCount : uint64 | |
val mutable OtherTransferCount : uint64 | |
[<Struct>] | |
type JOBOBJECT_BASIC_LIMIT_INFORMATION = | |
val mutable PerProcessUserTimeLimit : int64 | |
val mutable PerJobUserTimeLimit : int64 | |
val mutable LimitFlags : int16 | |
val mutable MinimumWorkingSetSize : UIntPtr | |
val mutable MaximumWorkingSetSize : UIntPtr | |
val mutable ActiveProcessLimit : int16 | |
val mutable Affinity : int64 | |
val mutable PriorityClass : int16 | |
val mutable SchedulingClass : int16 | |
[<Struct>] | |
type JOBOBJECT_EXTENDED_LIMIT_INFORMATION = | |
val mutable BasicLimitInformation : JOBOBJECT_BASIC_LIMIT_INFORMATION | |
val mutable IoInfo : IO_COUNTERS | |
val mutable ProcessMemoryLeft : uint32 | |
val mutable JobMemoryLimit : uint32 | |
val mutable PeakProcessMemoryUsed : uint32 | |
val mutable PeakJobMemoryUsed : uint32 | |
[<DllImport("kernel32.dll", CharSet = CharSet.Unicode)>] | |
extern IntPtr CreateJobObject(obj a, string lpName) | |
[<DllImport("kernel32.dll")>] | |
extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, uint32 cbJobObjectInfoLength) | |
[<DllImport("kernel32.dll", SetLastError = true)>] | |
extern bool AssignProcessToJobObject(IntPtr job, IntPtr proc) | |
[<DllImport("kernel32.dll")>] | |
extern bool CloseHandle(IntPtr hObject) | |
type Job() = | |
let mutable isDisposed = false | |
let mutable handle = CreateJobObject(null, null) | |
do | |
let mutable info = JOBOBJECT_BASIC_LIMIT_INFORMATION() | |
info.LimitFlags <- 0x2000s | |
let mutable extendedInfo = JOBOBJECT_EXTENDED_LIMIT_INFORMATION() | |
extendedInfo.BasicLimitInformation <- info | |
let length = Marshal.SizeOf(typeof<JOBOBJECT_EXTENDED_LIMIT_INFORMATION>) | |
let extendedInfoPtr = Marshal.AllocHGlobal(length) | |
Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false) | |
if not (SetInformationJobObject(handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, uint32 length)) then | |
failwithf "Unable to set information. Error: %i" (Marshal.GetLastWin32Error()) | |
member private __.Dispose(_isDisposing) = | |
if isDisposed then () | |
else | |
CloseHandle(handle) |> ignore | |
handle <- IntPtr.Zero | |
isDisposed <- true | |
member __.AddProcess(handleProc) = | |
AssignProcessToJobObject(handle, handleProc) | |
interface IDisposable with | |
member this.Dispose() = | |
this.Dispose(true) | |
GC.SuppressFinalize(this) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I get a 203 error on line 79 on Windows 10.