P/Invoke を使用した CreateJobObject と SetInformationJobObject の実装例
この例では、ジョブ オブジェクト (CreateJobObject) を作成し、その基本設定を行う方法を示します。ジョブが終了したときにジョブに関連付けられたプロセスが確実に終了するようにするための制限情報 (SetInformationJobObject)
using System; using System.Diagnostics; using System.Runtime.InteropServices; namespace JobObjectPInvoke { class Program { const int JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x2000; [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] static extern IntPtr CreateJobObject(IntPtr a, string lpName); [DllImport("kernel32.dll")] static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, UInt32 cbJobObjectInfoLength); [DllImport("kernel32.dll", SetLastError = true)] static extern bool CloseHandle(IntPtr hObject); static void Main() { // Get a handle to the current process. IntPtr currentProcessHandle = Process.GetCurrentProcess().Handle; // Create a job object. IntPtr jobObjectHandle = CreateJobObject(IntPtr.Zero, null); if (jobObjectHandle == IntPtr.Zero) { throw new Exception($"Failed to create job object: {Marshal.GetLastWin32Error()}"); } // Set the limit information for the job object. JOBOBJECT_BASIC_LIMIT_INFORMATION jobLimitInfo = new JOBOBJECT_BASIC_LIMIT_INFORMATION { LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE }; int sizeOfJobLimitInfo = Marshal.SizeOf(jobLimitInfo); IntPtr ptrJobLimitInfo = Marshal.AllocHGlobal(sizeOfJobLimitInfo); Marshal.StructureToPtr(jobLimitInfo, ptrJobLimitInfo, false); if (!SetInformationJobObject(jobObjectHandle, JobObjectInfoType.BasicLimitInformation, ptrJobLimitInfo, (uint)sizeOfJobLimitInfo)) { throw new Exception($"Failed to set job limit information: {Marshal.GetLastWin32Error()}"); } // Add the current process to the job object. if (!AssignProcessToJobObject(jobObjectHandle, currentProcessHandle)) { throw new Exception($"Failed to add process to job object: {Marshal.GetLastWin32Error()}"); } // Sleep for 10 seconds. System.Threading.Thread.Sleep(10000); // Close the job object. CloseHandle(jobObjectHandle); // The current process will terminate when the job object is closed. You can use this example to create a sandbox environment for your processes. } #region Helper Classes [StructLayout(LayoutKind.Sequential)] struct JOBOBJECT_BASIC_LIMIT_INFORMATION { public Int64 PerProcessUserTimeLimit; public Int64 PerJobUserTimeLimit; public UInt32 LimitFlags; public UIntPtr MinimumWorkingSetSize; public UIntPtr MaximumWorkingSetSize; public UInt32 ActiveProcessLimit; public UIntPtr Affinity; public UInt32 PriorityClass; public UInt32 SchedulingClass; } public enum JobObjectInfoType { AssociateCompletionPortInformation = 7, BasicLimitInformation = 2, BasicUIRestrictions = 4, EndOfJobTimeInformation = 6, ExtendedLimitInformation = 9, SecurityLimitInformation = 5 } #endregion } }
この拡張例は、ジョブ オブジェクトの作成、その基本的な制限情報の設定、およびジョブ オブジェクトへのプロセスの追加の完全な実装を示しています。 JOBOBJECT_LIMIT_KILL_ON_JOB_CLOSE フラグは、ジョブ オブジェクトが閉じられたときにジョブに関連付けられたすべてのプロセスが終了することを保証し、プロセスによって使用されるすべてのリソースが適切にクリーンアップされることを保証します。
以上がP/Invoke を使用して C# でジョブ オブジェクトを作成および管理し、プロセスを確実に終了する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。