Contoh Kerja CreateJobObject/SetInformationJobObject PInvoke dalam .NET
Soalan:
I' telah bergelut untuk mencipta contoh yang berfungsi menggunakan CreateJobObject dan Kaedah SetInformationJobObject melalui PInvoke. Walaupun pelbagai percubaan, saya menghadapi ralat semasa cuba menetapkan JOBOBJECT_BASIC_LIMIT_INFORMATION menggunakan kaedah SetInformationJobObject.
Jawapan:
Untuk menangani isu anda, mari kita teliti selok-belok bekerja dengan CreateJobObject dan SetInformationJobObject dalam .NET melalui PInvoke. Berikut ialah panduan langkah demi langkah dengan contoh berfungsi:
1. Cipta Objek Kerja:
Pertama, kami akan mencipta objek kerja menggunakan kaedah CreateJobObject. Kaedah ini mengambil dua hujah: atribut keselamatan dan nama kerja (yang akan kami biarkan kosong).
IntPtr jobHandle = CreateJobObject( null , null );
2. Tambah Proses pada Objek Kerja:
Seterusnya, kita perlu menetapkan proses kepada objek kerja yang baru dibuat. Kaedah AssignProcessToJobObject digunakan untuk tujuan ini.
AssignProcessToJobObject( jobHandle , myProcess.Handle ); AssignProcessToJobObject( jobHandle , Process.GetCurrentProcess().Handle );
3. Tetapkan Had Kerja:
Sekarang, kami akan menetapkan had kerja menggunakan kaedah SetInformationJobObject. Kami akan memberi tumpuan khusus pada menetapkan bendera 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 ) )
Dalam kod ini, kami telah menentukan struktur JOBOBJECT_BASIC_LIMIT_INFORMATION dan menetapkan LimitFlags kepada JOB_OBJECT_LIMIT_BILL_ONSEJ. Ini memastikan bahawa apabila satu proses dalam objek kerja ditamatkan, proses lain juga akan ditamatkan secara automatik.
Contoh Kod Lengkap:
Berikut ialah contoh kod lengkap yang menggabungkan langkah berikut:
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 ) ) } }
Kod ini akan mencipta objek kerja, menambah proses semasa dan proses lain (dinyatakan oleh myProcess) ke objek kerja dan tetapkan bendera JOBOBJECT_LIMIT_KILL_ON_JOB_CLOSE. Dengan berbuat demikian, apabila sama ada proses semasa atau myProcess ditamatkan, proses lain juga akan ditamatkan secara automatik.
Atas ialah kandungan terperinci Cara Menggunakan CreateJobObject dan SetInformationJobObject dengan PInvoke dalam .NET untuk Mengurus Penamatan Proses?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!