IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
WindowsChildProcessTracker.cs
Go to the documentation of this file.
1using System;
2using System.ComponentModel;
3using System.Diagnostics;
4using System.Runtime.InteropServices;
5
7{
8
16 {
17
18 enum JobObjectInfoType
19 {
20 AssociateCompletionPortInformation = 7,
21 BasicLimitInformation = 2,
22 BasicUIRestrictions = 4,
23 EndOfJobTimeInformation = 6,
24 ExtendedLimitInformation = 9,
25 SecurityLimitInformation = 5,
26 GroupInformation = 11
27 }
28
29 [StructLayout(LayoutKind.Sequential)]
30 struct JOBOBJECT_BASIC_LIMIT_INFORMATION
31 {
32 public Int64 PerProcessUserTimeLimit;
33 public Int64 PerJobUserTimeLimit;
34 public JOBOBJECTLIMIT LimitFlags;
35 public UIntPtr MinimumWorkingSetSize;
36 public UIntPtr MaximumWorkingSetSize;
37 public UInt32 ActiveProcessLimit;
38 public Int64 Affinity;
39 public UInt32 PriorityClass;
40 public UInt32 SchedulingClass;
41 }
42
43 [Flags]
44 enum JOBOBJECTLIMIT : uint
45 {
46 JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x2000
47 }
48
49 [StructLayout(LayoutKind.Sequential)]
50 struct IO_COUNTERS
51 {
52 public UInt64 ReadOperationCount;
53 public UInt64 WriteOperationCount;
54 public UInt64 OtherOperationCount;
55 public UInt64 ReadTransferCount;
56 public UInt64 WriteTransferCount;
57 public UInt64 OtherTransferCount;
58 }
59
60 [StructLayout(LayoutKind.Sequential)]
61 struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION
62 {
63 public JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation;
64 public IO_COUNTERS IoInfo;
65 public UIntPtr ProcessMemoryLimit;
66 public UIntPtr JobMemoryLimit;
67 public UIntPtr PeakProcessMemoryUsed;
68 public UIntPtr PeakJobMemoryUsed;
69 }
70
76 public static void AddProcess(Process process)
77 {
78 if (s_jobHandle != IntPtr.Zero)
79 {
80 bool success = AssignProcessToJobObject(s_jobHandle, process.Handle);
81 if (!success && !process.HasExited)
82 throw new Win32Exception();
83 }
84 }
85
87 {
88 // This feature requires Windows 8 or later. To support Windows 7 requires
89 // registry settings to be added if you are using Visual Studio plus an
90 // app.manifest change.
91 // https://stackoverflow.com/a/4232259/386091
92 // https://stackoverflow.com/a/9507862/386091
93 if (Environment.OSVersion.Version < new Version(6, 2))
94 return;
95
96 // The job name is optional (and can be null) but it helps with diagnostics.
97 // If it's not null, it has to be unique. Use SysInternals' Handle command-line
98 // utility: handle -a ChildProcessTracker
99 string jobName = "ChildProcessTracker" + Process.GetCurrentProcess().Id;
100 s_jobHandle = CreateJobObject(IntPtr.Zero, jobName);
101
102 var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION();
103
104 // This is the key flag. When our process is killed, Windows will automatically
105 // close the job handle, and when that happens, we want the child processes to
106 // be killed, too.
107 info.LimitFlags = JOBOBJECTLIMIT.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
108
109 var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION();
110 extendedInfo.BasicLimitInformation = info;
111
112 int length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
113 IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length);
114 try
115 {
116 Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);
117
118 if (!SetInformationJobObject(s_jobHandle, JobObjectInfoType.ExtendedLimitInformation,
119 extendedInfoPtr, (uint)length))
120 {
121 throw new Win32Exception();
122 }
123 }
124 finally
125 {
126 Marshal.FreeHGlobal(extendedInfoPtr);
127 }
128 }
129
130 [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
131 static extern IntPtr CreateJobObject(IntPtr lpJobAttributes, string name);
132
133 [DllImport("kernel32.dll")]
134 static extern bool SetInformationJobObject(IntPtr job, JobObjectInfoType infoType,
135 IntPtr lpJobObjectInfo, uint cbJobObjectInfoLength);
136
137 [DllImport("kernel32.dll", SetLastError = true)]
138 static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process);
139
140 // Windows will automatically close any open job handles when our process terminates.
141 // This can be verified by using SysInternals' Handle utility. When the job handle
142 // is closed, the child processes will be killed.
143 private static readonly IntPtr s_jobHandle;
144 }
145
146}
Allows processes to be automatically killed if this parent process unexpectedly quits....
static void AddProcess(Process process)
Add the process to be tracked. If our current process is killed, the child processes that we are trac...