本文介绍了工作CreateJobObject / SetInformationJobObject的PInvoke在.NET的例子吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我挣扎放在一起pinvoke'ing CreateJobObject和SetInformationJobObject的工作示例。通过各种谷歌搜索(包括俄罗斯和中国的职位!)我拼凑以下code。我认为,基于平台的JOBOBJECT_BASIC_LIMIT_INFORMATION变化定义(六十四分之三十二位)。该CreateJobObject / AssignProcessToJobObject的似乎的工作。 SetInformationJobObject失败 - 无论是与错误24或87。

 过程myProcess //填充别处

//创建工作和放大器;分配此过程,另一个过程到作业
IntPtr的jobHandle = CreateJobObject(NULL,NULL);
AssignProcessToJobObject(jobHandle,myProcess.Handle);
AssignProcessToJobObject(jobHandle,Process.GetCurrentProcess()办理。);

//确保杀死一个进程杀死他人
JOBOBJECT_BASIC_LIMIT_INFORMATION限额=新JO​​BOBJECT_BASIC_LIMIT_INFORMATION();
limits.LimitFlags =(短期)LimitFlags.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
IntPtr的pointerToJobLimitInfo = Marshal.AllocHGlobal(Marshal.SizeOf(限制));
Marshal.StructureToPtr(极限,pointerToJobLimitInfo,假);
SetInformationJobObject(工作,JOBOBJECTINFOCLASS.JobObjectBasicLimitInformation,pionterToJobLimitInfo,(UINT)Marshal.SizeOf(限制))
...


        [的DllImport(KERNEL32.DLL,入口点=CreateJobObjectW,字符集= CharSet.Uni code)
        公共静态外部的IntPtr CreateJobObject(SecurityAttributes的JobAttributes,串lpName);

        公共类SecurityAttributes
        {

            公众诠释nLength; //无用场= 0
            公众的IntPtr pSecurityDescriptor; //хз))
            公共BOOL bInheritHandle; //Возможностьнаследования

            公共SecurityAttributes()
            {
                this.bInheritHandle = TRUE;
                this.nLength = 0;
                this.pSecurityDescriptor = IntPtr.Zero;
            }
        }

        [的DllImport(KERNEL32.DLL)
        静态外部布尔SetInformationJobObject(IntPtr的hJob,JOBOBJECTINFOCLASS JobObjectInfoClass,IntPtr的lpJobObjectInfo,UINT cbJobObjectInfoLength);

        公共枚举JOBOBJECTINFOCLASS
        {
            JobObjectAssociateCompletionPortInformation = 7,
            JobObjectBasicLimitInformation = 2,
            JobObjectBasicUIRestrictions = 4,
            JobObjectEndOfJobTimeInformation = 6,
            JobObjectExtendedLimitInformation = 9,
            JobObjectSecurityLimitInformation = 5
        }


        [StructLayout(LayoutKind.Sequential)
        结构JOBOBJECT_BASIC_LIMIT_INFORMATION
        {
            公众的Int64 PerProcessUserTimeLimit;
            公众的Int64 PerJobUserTimeLimit;
            公众的Int16 LimitFlags;
            公共UIntPtr MinimumWorkingSetSize;
            公共UIntPtr MaximumWorkingSetSize;
            公众的Int16 ActiveProcessLimit;
            公共Int64的亲和力;
            公众的Int16的priorityClass;
            公众的Int16 SchedulingClass;
        }

        公共枚举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 = 00000001
        }


        [的DllImport(KERNEL32.DLL)
        [返回:的MarshalAs(UnmanagedType.Bool)
        静态外部布尔Assi​​gnProcessToJobObject(IntPtr的hJob,IntPtr的hProcess);

        [StructLayout(LayoutKind.Sequential)
        公共结构SECURITY_ATTRIBUTES
        {
            公众诠释nLength;
            公众的IntPtr lpSecurityDescriptor;
            公众诠释bInheritHandle;
        }
 

解决方案

这可能是有点晚了,但仍。

我尝试了所有在这里的例子,但没有人是在32位和64位模式,同时为我工作。最后,我被要求检查所有的签名,自己并创建相应的PInvoke程序。我想,别人可能会有所帮助。

声明:该解决方案是基于马特豪厄尔斯的回答

 使用系统;
使用System.Diagnostics程序;
使用了System.Runtime.InteropServices;

命名空间JobManagement
{
    公共类职位:IDisposable的
    {
        [的DllImport(KERNEL32.DLL,字符集= CharSet.Uni code)
        静态外部的IntPtr CreateJobObject(IntPtr的一个,串lpName);

        [的DllImport(KERNEL32.DLL)
        静态外部布尔SetInformationJobObject(IntPtr的hJob,JobObjectInfoType信息类型,IntPtr的lpJobObjectInfo,UInt32的cbJobObjectInfoLength);

        [的DllImport(KERNEL32.DLL,SetLastError =真)
        静态外部布尔Assi​​gnProcessToJobObject(IntPtr的工作,IntPtr的过程);

        私人IntPtr的手柄;
        私人BOOL处置;

        公开招聘()
        {
            处理= CreateJobObject(IntPtr.Zero,NULL);

            VAR信息=新JOBOBJECT_BASIC_LIMIT_INFORMATION
            {
                LimitFlags =为0x2000
            };

            VAR extendedInfo =新JOBOBJECT_EXTENDED_LIMIT_INFORMATION
            {
                BasicLimitInformation =信息
            };

            INT长度= Marshal.SizeOf(typeof运算(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
            IntPtr的extendedInfoPtr = Marshal.AllocHGlobal(长);
            Marshal.StructureToPtr(extendedInfo,extendedInfoPtr,假);

            如果(!SetInformationJobObject(手柄,JobObjectInfoType.ExtendedLimitInformation,extendedInfoPtr,(UINT)的长度))
                抛出新的异常(的String.Format(无法​​设置信息的错误:{0},Marshal.GetLastWin32Error()));
        }

        公共无效的Dispose()
        {
            处置(真);
            GC.Sup pressFinalize(本);
        }

        私人无效的Dispose(BOOL处置)
        {
            如果(处置)
                返回;

            如果(处置){}

            关闭();
            处置= TRUE;
        }

        公共无效关闭()
        {
            Win32.CloseHandle(手柄);
            处理= IntPtr.Zero;
        }

        公共BOOL AddProcess(IntPtr的processHandle)
        {
            返回AssignProcessToJobObject(手柄,processHandle);
        }

        公共BOOL AddProcess(INT进程ID)
        {
            返回AddProcess(Process.GetProcessById(进程ID).handle的);
        }

    }

    #地区的辅助类

    [StructLayout(LayoutKind.Sequential)
    结构IO_COUNTERS
    {
        公共UINT64 ReadOperationCount;
        公共UINT64 WriteOperationCount;
        公共UINT64 OtherOperationCount;
        公共UINT64 ReadTransferCount;
        公共UINT64 WriteTransferCount;
        公共UINT64 OtherTransferCount;
    }


    [StructLayout(LayoutKind.Sequential)
    结构JOBOBJECT_BASIC_LIMIT_INFORMATION
    {
        公众的Int64 PerProcessUserTimeLimit;
        公众的Int64 PerJobUserTimeLimit;
        公共UInt32的LimitFlags;
        公共UIntPtr MinimumWorkingSetSize;
        公共UIntPtr MaximumWorkingSetSize;
        公共UInt32的ActiveProcessLimit;
        公共UIntPtr亲和力;
        公共UInt32的的priorityClass;
        公共UInt32的SchedulingClass;
    }

    [StructLayout(LayoutKind.Sequential)
    公共结构SECURITY_ATTRIBUTES
    {
        公共UInt32的nLength;
        公众的IntPtr lpSecurityDescriptor;
        公众的Int32 bInheritHandle;
    }

    [StructLayout(LayoutKind.Sequential)
    结构JOBOBJECT_EXTENDED_LIMIT_INFORMATION
    {
        公共JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation;
        公共IO_COUNTERS Io​​Info;
        公共UIntPtr ProcessMemoryLimit;
        公共UIntPtr JobMemoryLimit;
        公共UIntPtr PeakProcessMemoryUsed;
        公共UIntPtr PeakJobMemoryUsed;
    }

    公共枚举JobObjectInfoType
    {
        AssociateCompletionPortInformation = 7,
        BasicLimitInformation = 2,
        BasicUIRestrictions = 4,
        EndOfJobTimeInformation = 6,
        ExtendedLimitInformation = 9,
        SecurityLimitInformation = 5,
        GroupInformation = 11
    }

    #endregion

}
 

I'm struggling to put together a working example of pinvoke'ing CreateJobObject and SetInformationJobObject. Through various google searches (including Russian and Chinese posts!) I've cobbled together the following code. I think the definition of JOBOBJECT_BASIC_LIMIT_INFORMATION changes based on platform (32/64-bit). The CreateJobObject/AssignProcessToJobObject seems to work. SetInformationJobObject fails - either with error 24 or 87.

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 ) )
...


        [DllImport( "kernel32.dll" , EntryPoint = "CreateJobObjectW" , CharSet = CharSet.Unicode )]
        public static extern IntPtr CreateJobObject( SecurityAttributes JobAttributes , string lpName );

        public class SecurityAttributes
        {

            public int nLength; //Useless field = 0
            public IntPtr pSecurityDescriptor; //хз))
            public bool bInheritHandle; //Возможность наследования

            public SecurityAttributes()
            {
                this.bInheritHandle = true;
                this.nLength = 0;
                this.pSecurityDescriptor = IntPtr.Zero;
            }
        }

        [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 );

        [StructLayout( LayoutKind.Sequential )]
        public struct SECURITY_ATTRIBUTES
        {
            public int nLength;
            public IntPtr lpSecurityDescriptor;
            public int bInheritHandle;
        }
解决方案

This can be little bit late, but still.

I tried all of the examples here, but no one was working for me in 32 and 64 bit mode simultaneously. Finally, I was required to examine all the signatures myself and create corresponding PInvoke routines. I think, somebody else could find this helpful.

Disclaimer: the solution is based on Matt Howells' answer.

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

namespace JobManagement
{
    public class Job : IDisposable
    {
        [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 AssignProcessToJobObject(IntPtr job, IntPtr process);

        private IntPtr handle;
        private bool disposed;

        public Job()
        {
            handle = CreateJobObject(IntPtr.Zero, null);

            var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION
            {
                LimitFlags = 0x2000
            };

            var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION
            {
                BasicLimitInformation = info
            };

            int length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
            IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length);
            Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);

            if (!SetInformationJobObject(handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length))
                throw new Exception(string.Format("Unable to set information.  Error: {0}", Marshal.GetLastWin32Error()));
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            if (disposed)
                return;

            if (disposing) { }

            Close();
            disposed = true;
        }

        public void Close()
        {
            Win32.CloseHandle(handle);
            handle = IntPtr.Zero;
        }

        public bool AddProcess(IntPtr processHandle)
        {
            return AssignProcessToJobObject(handle, processHandle);
        }

        public bool AddProcess(int processId)
        {
            return AddProcess(Process.GetProcessById(processId).Handle);
        }

    }

    #region Helper classes

    [StructLayout(LayoutKind.Sequential)]
    struct IO_COUNTERS
    {
        public UInt64 ReadOperationCount;
        public UInt64 WriteOperationCount;
        public UInt64 OtherOperationCount;
        public UInt64 ReadTransferCount;
        public UInt64 WriteTransferCount;
        public UInt64 OtherTransferCount;
    }


    [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;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct SECURITY_ATTRIBUTES
    {
        public UInt32 nLength;
        public IntPtr lpSecurityDescriptor;
        public Int32 bInheritHandle;
    }

    [StructLayout(LayoutKind.Sequential)]
    struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION
    {
        public JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation;
        public IO_COUNTERS IoInfo;
        public UIntPtr ProcessMemoryLimit;
        public UIntPtr JobMemoryLimit;
        public UIntPtr PeakProcessMemoryUsed;
        public UIntPtr PeakJobMemoryUsed;
    }

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

    #endregion

}

这篇关于工作CreateJobObject / SetInformationJobObject的PInvoke在.NET的例子吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 14:57