Exemple de travail de CreateJobObject/SetInformationJobObject PInvoke dans .NET
Question :
Je' J'ai eu du mal à créer un exemple fonctionnel d'utilisation des méthodes CreateJobObject et SetInformationJobObject via PInvoquer. Malgré diverses tentatives, je rencontre des erreurs lorsque j'essaie de définir le JOBOBJECT_BASIC_LIMIT_INFORMATION à l'aide de la méthode SetInformationJobObject.
Réponse :
Pour résoudre votre problème, examinons les subtilités de travailler avec CreateJobObject et SetInformationJobObject dans .NET via PInvoke. Voici un guide étape par étape avec un exemple fonctionnel :
1. Créer un objet Job :
Tout d'abord, nous allons créer un objet job à l'aide de la méthode CreateJobObject. Cette méthode prend deux arguments : un attribut de sécurité et le nom du travail (que nous laisserons vide).
IntPtr jobHandle = CreateJobObject( null , null );
2. Ajouter des processus à l'objet de travail :
Ensuite, nous devons attribuer des processus à notre objet de travail nouvellement créé. La méthode AssignProcessToJobObject est utilisée à cet effet.
AssignProcessToJobObject( jobHandle , myProcess.Handle ); AssignProcessToJobObject( jobHandle , Process.GetCurrentProcess().Handle );
3. Définir les limites des tâches :
Maintenant, nous allons définir les limites des tâches à l'aide de la méthode SetInformationJobObject. Nous nous concentrerons spécifiquement sur la définition de l'indicateur 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 ) )
Dans ce code, nous avons défini la structure JOBOBJECT_BASIC_LIMIT_INFORMATION et défini les LimitFlags sur JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE. Cela garantit que lorsqu'un processus dans l'objet de travail est terminé, les autres processus sont également automatiquement terminés.
Exemple de code complet :
Voici l'exemple de code complet qui intègre ces étapes :
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 ) ) } }
Ce code créera un objet de travail, ajoutera le processus actuel et un autre processus (spécifié par myProcess) au travail objet et définissez l'indicateur JOBOBJECT_LIMIT_KILL_ON_JOB_CLOSE. Ce faisant, lorsque le processus en cours ou myProcess sera terminé, l'autre processus sera également terminé automatiquement.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!