http://www.cnblogs.com/TianFang/archive/2010/05/19/1739614.html
正好碰到这位一样的问题,就直接转过来了
这是个我在C#调用批处理文件时遇到的问题。首先我通过Process.Start方法调用一个批处理文件,那个批处理文件里面则调用了一大堆程序。当退出C#程序时,我在程序中结束杀掉了那个批处理文件的Process,但是,那个批处理所调用的子进程却无法像直接调用批处理文件那样随着批处理文件的进程一起被杀掉,而是自动向上提升成为了独立的进程。
在网上查了一下,可以通过NtQueryInformationProcess函数查询子进程的信息,并同时也查到了一段杀掉进程及所有子进程的C#代码,有需要的朋友可以参考一下。
代码
static
class
ProcessExtend
{
// [StructLayout(LayoutKind.Sequential)]
private struct ProcessBasicInformation
{
public int ExitStatus;
public int PebBaseAddress;
public int AffinityMask;
public int BasePriority;
public uint UniqueProcessId;
public uint InheritedFromUniqueProcessId;
}
[DllImport( " ntdll.dll " )]
static extern int NtQueryInformationProcess(
IntPtr hProcess,
int processInformationClass /* 0 */ ,
ref ProcessBasicInformation processBasicInformation,
uint processInformationLength,
out uint returnLength
);
public static void KillProcessTree( this Process parent)
{
var processes = Process.GetProcesses();
foreach (var p in processes)
{
var pbi = new ProcessBasicInformation();
try
{
uint bytesWritten;
if (NtQueryInformationProcess(p.Handle, 0 , ref pbi, ( uint )Marshal.SizeOf(pbi), out bytesWritten) == 0 ) // == 0 is OK
if (pbi.InheritedFromUniqueProcessId == parent.Id)
using (var newParent = Process.GetProcessById(( int )pbi.UniqueProcessId))
newParent.KillProcessTree();
}
catch { }
}
parent.Kill();
}
}
{
// [StructLayout(LayoutKind.Sequential)]
private struct ProcessBasicInformation
{
public int ExitStatus;
public int PebBaseAddress;
public int AffinityMask;
public int BasePriority;
public uint UniqueProcessId;
public uint InheritedFromUniqueProcessId;
}
[DllImport( " ntdll.dll " )]
static extern int NtQueryInformationProcess(
IntPtr hProcess,
int processInformationClass /* 0 */ ,
ref ProcessBasicInformation processBasicInformation,
uint processInformationLength,
out uint returnLength
);
public static void KillProcessTree( this Process parent)
{
var processes = Process.GetProcesses();
foreach (var p in processes)
{
var pbi = new ProcessBasicInformation();
try
{
uint bytesWritten;
if (NtQueryInformationProcess(p.Handle, 0 , ref pbi, ( uint )Marshal.SizeOf(pbi), out bytesWritten) == 0 ) // == 0 is OK
if (pbi.InheritedFromUniqueProcessId == parent.Id)
using (var newParent = Process.GetProcessById(( int )pbi.UniqueProcessId))
newParent.KillProcessTree();
}
catch { }
}
parent.Kill();
}
}