当父NT服务被终止/崩溃时,终止子进程

本文关键字:终止 子进程 崩溃 服务 当父 NT | 更新日期: 2023-09-27 18:28:09

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

为此,我找到了使用当父进程终止时终止子进程

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

异常:_COMPlusExceptionCode=-532462766

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

我使用的是Win2k8 R2服务器和C#

[编辑1]异常:GenericParameterAttributes="((System.Reflection.RuntimeConstructorInfo)(例如_exceptionMethod)).ReflectedType).GenericParameterAttributes"引发了类型为"System.InvalidOperationException"的异常{"方法只能在Type.IsGenericParameter为true的类型上调用。"}

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

编辑3:在我的64位win2k8R2服务器机器的NT Servce的情况下,正确的长度预期为144,而在上面的后定义为112

编辑4:这是唯一的方法吗?还有其他选择吗?

当父NT服务被终止/崩溃时,终止子进程

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

上面线程中定义的结构对32位应用程序有效,并且
我的NT服务是一个64位的应用程序,它需要对进行一些更改

所做的更改

  • 首先将SetInformationJobObject的DLL导入更改为

    [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与UInt32DWORD=Int32

经过这些改变,一切都很好。