Maison > développement back-end > C++ > Comment utiliser CreateJobObject et SetInformationJobObject avec PInvoke dans .NET pour gérer la fin des processus ?

Comment utiliser CreateJobObject et SetInformationJobObject avec PInvoke dans .NET pour gérer la fin des processus ?

DDD
Libérer: 2024-12-27 13:46:10
original
597 Les gens l'ont consulté

How to Use CreateJobObject and SetInformationJobObject with PInvoke in .NET to Manage Process Termination?

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 );
Copier après la connexion

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 );
Copier après la connexion

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 ) )
Copier après la connexion

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 ) )
    }
}
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal