首页 >后端开发 >C++ >如何在 .NET 中将 CreateJobObject 和 SetInformationJobObject 与 PInvoke 结合使用来管理进程终止?

如何在 .NET 中将 CreateJobObject 和 SetInformationJobObject 与 PInvoke 结合使用来管理进程终止?

DDD
DDD原创
2024-12-27 13:46:10629浏览

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

.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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn