.NET 中 CreateJobObject/SetInformationJobObject PInvoke 的工作示例
问题:
我'一直在努力创建一个使用 CreateJobObject 的工作示例,并且通过 PInvoke 的 SetInformationJobObject 方法。尽管进行了各种尝试,但在尝试使用 SetInformationJobObject 方法设置 JOBOBJECT_BASIC_LIMIT_INFORMATION 时,我还是遇到了错误。
答案:
要解决您的问题,让我们深入研究其中的复杂性通过以下方式在 .NET 中使用 CreateJobObject 和 SetInformationJobObject P调用。这是带有功能示例的分步指南:
1。创建作业对象:
首先,我们将使用 CreateJobObject 方法创建一个作业对象。此方法采用两个参数:安全属性和作业名称(我们将其留空)。
IntPtr jobHandle = CreateJobObject( null , null );
2.将进程添加到作业对象:
接下来,我们需要将进程分配给新创建的作业对象。 AssignProcessToJobObject 方法就是用于此目的。
AssignProcessToJobObject( jobHandle , myProcess.Handle ); AssignProcessToJobObject( jobHandle , Process.GetCurrentProcess().Handle );
3.设置作业限制:
现在,我们将使用 SetInformationJobObject 方法设置作业限制。我们将特别关注设置 JOBOBJECT_LIMIT_KILL_ON_JOB_CLOSE 标志。
JOBOBJECT_BASIC_LIMIT_INFORMATION limits = new JOBOBJECT_BASIC_LIMIT_INFORMATION(); limits.LimitFlags = (short)LimitFlags.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; IntPtr pointerToJobLimitInfo = Marshal.AllocHGlobal( Marshal.SizeOf( limits ) ); Marshal.StructureToPtr( limits , pointerToJobLimitInfo , false ); SetInformationJobObject( job , JOBOBJECTINFOCLASS.JobObjectBasicLimitInformation , pionterToJobLimitInfo , ( uint )Marshal.SizeOf( limits ) )
在此代码中,我们定义了 JOBOBJECT_BASIC_LIMIT_INFORMATION 结构并将 LimitFlags 设置为 JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE。这确保了当作业对象中的一个进程终止时,其他进程也会自动终止。
完整代码示例:
这里是完整的代码示例,其中包含这些步骤:
using System; using System.Diagnostics; using System.Runtime.InteropServices; class Program { [DllImport( "kernel32.dll" , EntryPoint = "CreateJobObjectW" , CharSet = CharSet.Unicode )] public static extern IntPtr CreateJobObject( IntPtr JobAttributes , string lpName ); [DllImport( "kernel32.dll" )] static extern bool SetInformationJobObject( IntPtr hJob , JOBOBJECTINFOCLASS JobObjectInfoClass , IntPtr lpJobObjectInfo , uint cbJobObjectInfoLength ); public enum JOBOBJECTINFOCLASS { JobObjectAssociateCompletionPortInformation = 7 , JobObjectBasicLimitInformation = 2 , JobObjectBasicUIRestrictions = 4 , JobObjectEndOfJobTimeInformation = 6 , JobObjectExtendedLimitInformation = 9 , JobObjectSecurityLimitInformation = 5 } [StructLayout( LayoutKind.Sequential )] struct JOBOBJECT_BASIC_LIMIT_INFORMATION { public Int64 PerProcessUserTimeLimit; public Int64 PerJobUserTimeLimit; public Int16 LimitFlags; public UIntPtr MinimumWorkingSetSize; public UIntPtr MaximumWorkingSetSize; public Int16 ActiveProcessLimit; public Int64 Affinity; public Int16 PriorityClass; public Int16 SchedulingClass; } public enum LimitFlags { JOB_OBJECT_LIMIT_ACTIVE_PROCESS = 0x00000008 , JOB_OBJECT_LIMIT_AFFINITY = 0x00000010 , JOB_OBJECT_LIMIT_BREAKAWAY_OK = 0x00000800 , JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION = 0x00000400 , JOB_OBJECT_LIMIT_JOB_MEMORY = 0x00000200 , JOB_OBJECT_LIMIT_JOB_TIME = 0x00000004 , JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x00002000 , JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME = 0x00000040 , JOB_OBJECT_LIMIT_PRIORITY_CLASS = 0x00000020 , JOB_OBJECT_LIMIT_PROCESS_MEMORY = 0x00000100 , JOB_OBJECT_LIMIT_PROCESS_TIME = 0x00000002 , JOB_OBJECT_LIMIT_SCHEDULING_CLASS = 0x00000080 , JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK = 0x00001000 , JOB_OBJECT_LIMIT_WORKINGSET = 0x00000001 } [DllImport( "kernel32.dll" )] [return: MarshalAs( UnmanagedType.Bool )] static extern bool AssignProcessToJobObject( IntPtr hJob , IntPtr hProcess ); static void Main( string[] args ) { Process myProcess = // POPULATED SOMEWHERE ELSE // Create Job & assign this process and another process to the job IntPtr jobHandle = CreateJobObject( null , null ); AssignProcessToJobObject( jobHandle , myProcess.Handle ); AssignProcessToJobObject( jobHandle , Process.GetCurrentProcess().Handle ); // Ensure that killing one process kills the others JOBOBJECT_BASIC_LIMIT_INFORMATION limits = new JOBOBJECT_BASIC_LIMIT_INFORMATION(); limits.LimitFlags = (short)LimitFlags.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; IntPtr pointerToJobLimitInfo = Marshal.AllocHGlobal( Marshal.SizeOf( limits ) ); Marshal.StructureToPtr( limits , pointerToJobLimitInfo , false ); SetInformationJobObject( job , JOBOBJECTINFOCLASS.JobObjectBasicLimitInformation , pionterToJobLimitInfo , ( uint )Marshal.SizeOf( limits ) ) } }
此代码将创建一个作业对象,添加当前进程和另一个进程(由 myProcess 指定)到作业对象,并设置 JOBOBJECT_LIMIT_KILL_ON_JOB_CLOSE 标志。这样,当当前进程或 myProcess 终止时,另一个进程也会自动终止。
以上是如何在 .NET 中将 CreateJobObject 和 SetInformationJobObject 与 PInvoke 结合使用来管理进程终止?的详细内容。更多信息请关注PHP中文网其他相关文章!