如何杀死进程及子进程

这是个我在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();
        }
    }

 

PS:今天发现NtQueryInformationProcess函数在x64位程序上运行无效, 具体原因不明,Google了一下也没有找到答案,反而找到了另一种解决方案,通过WMI来实现的。在x86和x64下都可以使用。

View Code
static   void  KillProcessAndChildren( int  pid)
{
    ManagementObjectSearcher searcher 
=   new  ManagementObjectSearcher( " Select * From Win32_Process Where ParentProcessID= "   +  pid);
    ManagementObjectCollection moc 
=  searcher.Get();
    
foreach  (ManagementObject mo  in  moc)
    {
        KillProcessAndChildren(Convert.ToInt32(mo[
" ProcessID " ]));
    }
    
try
    {
        Process proc 
=  Process.GetProcessById(pid);
        Console.WriteLine(pid);
        proc.Kill();
    }
    
catch  (ArgumentException)
    { 
        
/*  process already exited  */
    }
}

 

转载于:https://www.cnblogs.com/TianFang/archive/2010/05/19/1739614.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值