在父NT服务被杀/崩溃时杀死子进程

时间:2013-08-19 16:09:58

标签: c# c++ .net winapi process

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

为此我找到了这样做的方法 Kill child process when parent process is killed

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

异常:_COMPlusExceptionCode = -532462766

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

我使用的是Win2k8 R2 Server机器和C#

[EDIT1] 例外: GenericParameterAttributes ='((System.Reflection.RuntimeConstructorInfo)(ex._exceptionMethod))。ReflectedType).GenericParameterAttributes'引发了类型'System.InvalidOperationException'的异常  {“方法只能在Type.IsGenericParameter为true的Type上调用。”}

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

编辑3:在我的64位win2k8R2服务器机器的NT Servce的情况下预期的正确长度似乎是144而不是上面的帖子中定义的112

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

1 个答案:

答案 0 :(得分:0)

问题出在我使用的结构声明中,如线程Kill child process when parent process is killed

中所定义

上述线程中定义的结构对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 structureJOBOBJECT_BASIC_LIMIT_INFORMATION structure我们应该按照应用程序使用数据类型 SIZE_T = UInt64 vs UInt32 DWORD = Int32

更改后,它工作正常。