首頁 > 後端開發 > C++ > 如何在 .NET 中將 CreateJobObject 和 SetInformationJobObject 與 PInvoke 結合使用來管理進程終止?

如何在 .NET 中將 CreateJobObject 和 SetInformationJobObject 與 PInvoke 結合使用來管理進程終止?

DDD
發布: 2024-12-27 13:46:10
原創
598 人瀏覽過

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中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板