C# AssignProcessToJobObject don';分配不当

C# AssignProcessToJobObject don';分配不当,c#,object,jobs,flags,assign,C#,Object,Jobs,Flags,Assign,我尝试使用以下方法将“job\u object\u limit\u kill\u on\u job\u close”设置为子进程: int pid = System.Diagnostics.Process.GetProcessesByName("Child")[0].Id; Job job = new Job("TEST JOB"); job.AddProcess(Process.GetProcessById((int)pid).Handle); 使用Process Explorer,我看到分

我尝试使用以下方法将“job\u object\u limit\u kill\u on\u job\u close”设置为子进程:

int pid = System.Diagnostics.Process.GetProcessesByName("Child")[0].Id;
Job job = new Job("TEST JOB");
job.AddProcess(Process.GetProcessById((int)pid).Handle);
使用Process Explorer,我看到分配给子进程的作业“测试作业”,但不知何故没有列出作业限制…它只是空的

这是什么原因造成的

GetLastWin32Error
只需返回
0

下面是我正在使用的类:

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(string jobName)
    {
        handle = CreateJobObject(IntPtr.Zero, jobName);

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

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

    public void Close()
    {
        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

没有问题,Process Explorer只是没有显示关闭时终止标志。它将展示什么


您是否测试并确保您的子流程在结束作业时结束?只要你的程序运行正常,你就不必担心外部工具会显示什么。

我已经编辑了你的标题。请看,“,其中的共识是“不,他们不应该”。好吧,我很抱歉:Herenop的新功能不起作用。客户机进程仍在运行idk为什么。但对于我来说,这是一个process explorer问题:)