首页 > 后端开发 > C++ > 如何在C#中使用P/Invoke创建和管理作业对象以确保进程终止?

如何在C#中使用P/Invoke创建和管理作业对象以确保进程终止?

Mary-Kate Olsen
发布: 2025-01-04 01:54:38
原创
738 人浏览过

How to Use P/Invoke to Create and Manage Job Objects in C# to Ensure Process Termination?

使用 P/Invoke 实现 CreateJobObject 和 SetInformationJobObject 的示例

此示例演示如何创建作业对象 (CreateJobObject) 并设置其基本信息限制信息 (SetInformationJobObject),以确保在作业执行时与作业关联的进程终止

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace JobObjectPInvoke
{
    class Program
    {
        const int JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x2000;

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
        static extern IntPtr CreateJobObject(IntPtr a, string lpName);

        [DllImport("kernel32.dll")]
        static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, UInt32 cbJobObjectInfoLength);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool CloseHandle(IntPtr hObject);

        static void Main()
        {
            // Get a handle to the current process.
            IntPtr currentProcessHandle = Process.GetCurrentProcess().Handle;

            // Create a job object.
            IntPtr jobObjectHandle = CreateJobObject(IntPtr.Zero, null);
            if (jobObjectHandle == IntPtr.Zero)
            {
                throw new Exception($"Failed to create job object: {Marshal.GetLastWin32Error()}");
            }

            // Set the limit information for the job object.
            JOBOBJECT_BASIC_LIMIT_INFORMATION jobLimitInfo = new JOBOBJECT_BASIC_LIMIT_INFORMATION
            {
                LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
            };

            int sizeOfJobLimitInfo = Marshal.SizeOf(jobLimitInfo);
            IntPtr ptrJobLimitInfo = Marshal.AllocHGlobal(sizeOfJobLimitInfo);
            Marshal.StructureToPtr(jobLimitInfo, ptrJobLimitInfo, false);

            if (!SetInformationJobObject(jobObjectHandle, JobObjectInfoType.BasicLimitInformation, ptrJobLimitInfo, (uint)sizeOfJobLimitInfo))
            {
                throw new Exception($"Failed to set job limit information: {Marshal.GetLastWin32Error()}");
            }

            // Add the current process to the job object.
            if (!AssignProcessToJobObject(jobObjectHandle, currentProcessHandle))
            {
                throw new Exception($"Failed to add process to job object: {Marshal.GetLastWin32Error()}");
            }

            // Sleep for 10 seconds.
            System.Threading.Thread.Sleep(10000);

            // Close the job object.
            CloseHandle(jobObjectHandle);

            // The current process will terminate when the job object is closed. You can use this example to create a sandbox environment for your processes.
        }

        #region Helper Classes

        [StructLayout(LayoutKind.Sequential)]
        struct JOBOBJECT_BASIC_LIMIT_INFORMATION
        {
            public Int64 PerProcessUserTimeLimit;
            public Int64 PerJobUserTimeLimit;
            public UInt32 LimitFlags;
            public UIntPtr MinimumWorkingSetSize;
            public UIntPtr MaximumWorkingSetSize;
            public UInt32 ActiveProcessLimit;
            public UIntPtr Affinity;
            public UInt32 PriorityClass;
            public UInt32 SchedulingClass;
        }

        public enum JobObjectInfoType
        {
            AssociateCompletionPortInformation = 7,
            BasicLimitInformation = 2,
            BasicUIRestrictions = 4,
            EndOfJobTimeInformation = 6,
            ExtendedLimitInformation = 9,
            SecurityLimitInformation = 5
        }

        #endregion
    }
}
登录后复制

这个扩展示例说明了创建作业对象、设置其基本限制信息以及向作业对象添加进程的完整实现。 JOBOBJECT_LIMIT_KILL_ON_JOB_CLOSE 标志确保当作业对象关闭时,与作业关联的任何进程都将被终止,从而确保进程使用的所有资源都被正确清理。

以上是如何在C#中使用P/Invoke创建和管理作业对象以确保进程终止?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板