1

我有一个 Windows NT 服务和一个第三方 exe,我想作为 NT 服务的子进程运行,这样一旦我的 NT 服务进程崩溃,这个子进程也会被杀死

为此,我找到了 在父进程被杀死时使用杀死子进程的方法

我尝试使用普通的父进程来实现它并正常工作,但是当我在 NT 服务中执行与父 SetInformationJobObject 方法相同的操作时,返回 false 和错误代码为 0 的异常

异常:_COMPlusExceptionCode = -532462766

导致此异常的正常进程和 NT 服务进程有什么区别?

我正在使用 Win2k8 R2 服务器机器和 C#

[EDIT1] Exception: GenericParameterAttributes = '(((System.Reflection.RuntimeConstructorInfo)(ex._exceptionMethod)).ReflectedType).GenericParameterAttributes' 抛出了类型为 'System.InvalidOperationException' 的异常 {"方法只能在类型上调用哪个 Type.IsGenericParameter 为真。"}

编辑 2:因为在使用 DLLImport 的函数定义中未将 SetLastError 设置为 true,所以最后一个错误是错误的 Correct ErrorCode 是 24,表示结构的错误长度,那么正确的结构应该是什么?

编辑 3:对于我的 64 位 win2k8R2 服务器机器,NT Servce 的预期正确长度似乎为 144,而上述帖子中定义的为 112

编辑 4:这是这样做的唯一方法,还有哪些其他选择?

4

1 回答 1

0

问题出在我使用的结构声明中,如父进程被杀死时线程杀死子进程中定义的那样

上述线程中定义的结构对 32 位应用程序有效,而
My NT Service 是 64 位应用程序,需要对其进行一些更改

所做的更改

  • 首先将SetInformationJobObject的DLL Import改为

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

    由于未设置 SetLastError 标志,它没有给我正确的错误代码,只有在获得正确的错误代码后,我才能得到它期望 144 字节长度的结构

  • 然后将 JOBOBJECT_BASIC_LIMIT_INFORMATION 和 JOBOBJECT_EXTENDED_LIMIT_INFORMATION 结构更改为以下

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

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

基本上按照JOBOBJECT_EXTENDED_LIMIT_INFORMATION 结构JOBOBJECT_BASIC_LIMIT_INFORMATION 结构,我们应该根据应用程序使用数据类型 SIZE_T = UInt64 vs UInt32 DWORD = Int32

更改后它工作正常。

于 2013-08-21T08:02:39.553 回答