0

我用 c# 创建了一个工作

    public WindowsJob()
    {
        m_handle = Kernel32Dll.CreateJobObject(IntPtr.Zero, null);
        SetJobInformation();
        SetJobCompletionPort();
    }

    private void SetJobInformation()
    {
        var info = new Win32Define.JOBOBJECT_BASIC_LIMIT_INFORMATION
        {
            LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE,

        };

        var extendedInfo = new Win32Define.JOBOBJECT_EXTENDED_LIMIT_INFORMATION
        {
            BasicLimitInformation = info
        };

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

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

i can catch JOB_OBJECT_MSG_NEW_PROCESS, JOB_OBJECT_MSG_EXIT_PROCESS, JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO, but i can't catch JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS (i write ac# program which throw new System.Exception("not handled") to kill itself, and it be caught by JOB_OBJECT_MSG_EXIT_PROCESS rather than JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS).

我尝试了本地程序,它也不能被 JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS 捕获。

为什么?我有什么错误吗?

4

1 回答 1

0

如果我们查看JOBOBJECT_ASSOCIATE_COMPLETION_PORT的文档,它看起来是发送进程退出通知的结构,我们会看到只有一组有限的退出代码被认为是异常退出。

例如,要让进程以 STATUS_ACCESS_VIOLATION 退出,请尝试以下 C++ 程序,看看是否收到异常退出通知。

void main()
{
    int* p = nullptr;
    *p = 42;
}

在我的测试中,以未处理异常退出的 .NET 应用程序的退出代码为 255,这不是列为异常退出的代码之一。

于 2013-11-25T05:46:56.063 回答