ホームページ >バックエンド開発 >C++ >.NET の PInvoke で CreateJobObject と SetInformationJobObject を使用してプロセスの終了を管理する方法

.NET の PInvoke で CreateJobObject と SetInformationJobObject を使用してプロセスの終了を管理する方法

DDD
DDDオリジナル
2024-12-27 13:46:10593ブラウズ

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 メソッドを使用してジョブ オブジェクトを作成します。このメソッドは、セキュリティ属性とジョブ名 (空のままにします) という 2 つの引数を取ります。

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 に設定しました。これにより、ジョブ オブジェクト内の 1 つのプロセスが終了すると、他のプロセスも自動的に終了します。

完全なコード例:

これが組み込まれた完全なコード例です。これらの手順:

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 の PInvoke で CreateJobObject と SetInformationJobObject を使用してプロセスの終了を管理する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。