当父进程被杀死时杀死子进程

我正在使用System.Diagnostics.Process应用程序中的类创建新流程。

我希望当我的应用程序崩溃时,该进程被终止。但是,如果我从任务管理器中杀死我的应用程序,则不会杀死子进程。

有什么方法可以使子进程依赖于父进程?

回答:

在这个论坛上,将“乔什”归功。

Application.Quit()并且Process.Kill()是可能的解决方案,但已证明是不可靠的。当主应用程序死亡时,您仍然可以运行子进程。我们真正想要的是子进程在主进程死亡后立即死亡。

解决方案是使用“作业对象” http://msdn.microsoft.com/zh-

cn/library/ms682409(VS.85).aspx。

这个想法是为您的主应用程序创建一个“作业对象”,并向该作业对象注册子进程。如果主进程终止,则操作系统将负责终止子进程。

public enum JobObjectInfoType

{

AssociateCompletionPortInformation = 7,

BasicLimitInformation = 2,

BasicUIRestrictions = 4,

EndOfJobTimeInformation = 6,

ExtendedLimitInformation = 9,

SecurityLimitInformation = 5,

GroupInformation = 11

}

[StructLayout(LayoutKind.Sequential)]

public struct SECURITY_ATTRIBUTES

{

public int nLength;

public IntPtr lpSecurityDescriptor;

public int bInheritHandle;

}

[StructLayout(LayoutKind.Sequential)]

struct JOBOBJECT_BASIC_LIMIT_INFORMATION

{

public Int64 PerProcessUserTimeLimit;

public Int64 PerJobUserTimeLimit;

public Int16 LimitFlags;

public UInt32 MinimumWorkingSetSize;

public UInt32 MaximumWorkingSetSize;

public Int16 ActiveProcessLimit;

public Int64 Affinity;

public Int16 PriorityClass;

public Int16 SchedulingClass;

}

[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_EXTENDED_LIMIT_INFORMATION

{

public JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation;

public IO_COUNTERS IoInfo;

public UInt32 ProcessMemoryLimit;

public UInt32 JobMemoryLimit;

public UInt32 PeakProcessMemoryUsed;

public UInt32 PeakJobMemoryUsed;

}

public class Job : IDisposable

{

[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]

static extern IntPtr CreateJobObject(object a, string lpName);

[DllImport("kernel32.dll")]

static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, uint cbJobObjectInfoLength);

[DllImport("kernel32.dll", SetLastError = true)]

static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process);

private IntPtr m_handle;

private bool m_disposed = false;

public Job()

{

m_handle = CreateJobObject(null, null);

JOBOBJECT_BASIC_LIMIT_INFORMATION info = new JOBOBJECT_BASIC_LIMIT_INFORMATION();

info.LimitFlags = 0x2000;

JOBOBJECT_EXTENDED_LIMIT_INFORMATION extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION();

extendedInfo.BasicLimitInformation = info;

int length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));

IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length);

Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);

if (!SetInformationJobObject(m_handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length))

throw new Exception(string.Format("Unable to set information. Error: {0}", Marshal.GetLastWin32Error()));

}

#region IDisposable Members

public void Dispose()

{

Dispose(true);

GC.SuppressFinalize(this);

}

#endregion

private void Dispose(bool disposing)

{

if (m_disposed)

return;

if (disposing) {}

Close();

m_disposed = true;

}

public void Close()

{

Win32.CloseHandle(m_handle);

m_handle = IntPtr.Zero;

}

public bool AddProcess(IntPtr handle)

{

return AssignProcessToJobObject(m_handle, handle);

}

}

看着构造函数…

JOBOBJECT_BASIC_LIMIT_INFORMATION info = new JOBOBJECT_BASIC_LIMIT_INFORMATION();

info.LimitFlags = 0x2000;

这里的关键是正确设置作业对象。在构造函数中,我将“限制”设置为0x2000,这是的数字值JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE

MSDN将该标志定义为:

当作业的最后一个句柄关闭时,导致与该作业关联的所有进程终止。

设置好此类后,您只需在作业中注册每个子进程。例如:

[DllImport("user32.dll", SetLastError = true)]

public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

Excel.Application app = new Excel.ApplicationClass();

uint pid = 0;

Win32.GetWindowThreadProcessId(new IntPtr(app.Hwnd), out pid);

job.AddProcess(Process.GetProcessById((int)pid).Handle);

以上是 当父进程被杀死时杀死子进程 的全部内容, 来源链接: utcz.com/qa/430345.html

回到顶部