C#结束进程及子进程

这是个我在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下都可以使用。

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 */
    }
}

到此这篇关于C#结束进程及子进程的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C#实现查杀本地与远程进程的方法

    本文实例讲述了C#实现查杀本地与远程进程的方法.分享给大家供大家参考. 具体实现方法如下: 复制代码 代码如下: using System; using System.Management; using System.Threading;   class xkill { public static void usage() { Console.WriteLine(); Console.WriteLine("xkill v1.0 Beta, By R&S"); Console.W

  • C#关闭指定名字进程的方法

    本文实例讲述了C#关闭指定名字进程的方法.分享给大家供大家参考.具体实现方法如下: public static void stopNamedProcess(string name) { foreach (Process p in System.Diagnostics.Process.GetProcessesByName(name)) { try { p.Kill(); p.WaitForExit(); } catch (Exception exp) { Console.WriteLine(exp

  • C#获取所有进程的方法

    在使用C#进行相关编程的时候,有时候我们需要获取系统相关的进程信息.那么在C#中如何获取系统的所有进程那?下面请跟小编一起来操作. 1.首先新建一个控制台程序,这里主要是为了方便演示,控制台程序相对比较简单,如下图所示: 2.然后导入进程相关的操作类,主要是diagnostics,如下图所示 3.然后我们调用Process类的GetProcesses方法,获取系统所以进程,注意是一个数组,图下图所示: 4.我们来看一下Process的相关解释说明,把鼠标放上去,看到如下图所示的内容 5.接下来我

  • C#中进程的挂起与恢复

    1. 源起: 仍然是模块化编程所引发的需求.产品经理难伺候,女产品经理更甚之~:p 纯属戏谑,技术方案与产品经理无关,芋头莫怪! VCU10项目重构,要求各功能模块以独立进程方式实现,比如:音视频转换模块,若以独立进程方式实现,如何控制其暂停.继续等功能呢? 线程可以Suspend.Resume,c#内置的Process没有此类方法,咋整? 山穷水尽疑无路,柳暗花明又一村.情到浓时清转薄,此情可待成追忆! 前篇描述了进程间数据传递方法,此篇亦以示例演示其间控制与数据交互方法.  2.未公开的AP

  • C#操作进程的方法介绍

    进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实体:在当代面向线程设计的计算机结构中,进程是线程的容器.程序是指令.数据及其组织形式的描述,进程是程序的实体. 下面为大家介绍C#是如何操作进程的. 1.获取当前程序中正在运行的所有进程 //1.获取本机所有进程 Process[] pro = Process.GetProcesses(); foreach (Pr

  • C#实现启动,关闭与查找进程的方法

    本文实例讲述了C#实现启动,关闭与查找进程的方法.分享给大家供大家参考,具体如下: 运行效果截图如下: 查找/列出进程很容易,但干掉进程得借助系统命令ntsd.exe,详细用法见下面的代码 : using System; using System.Diagnostics; using System.Windows.Forms; namespace ProcessDemo { public partial class Form1 : Form { public Form1() { Initiali

  • C#实现强制关闭当前程序进程

    /// <summary> /// 运行DOS命令 /// DOS关闭进程命令(ntsd -c q -p PID )PID为进程的ID /// </summary> /// <param name="command"></param> /// <returns></returns> public static string RunCmd(string command) { //實例一個Process類,啟動一個獨立

  • C#实现关闭其他程序窗口或进程代码分享

    在进行winform开发过程中有时候会需要关闭其他程序或者关闭进程,以前写过一篇相关介绍的文章,今天有同事问起来,于是在次翻出来和大家分享一下. 下面介绍我所知的两种方法,应该对大家有帮助,如果有朋友知道其他的方法,谢谢共享一下. 方法1 ProcName 需要关闭的进程名称 private bool closeProc(string ProcName) { bool result = false; System.Collections.ArrayList procList = new Syst

  • 如何在C# 中查找或结束程序域中的主、子进程

    有时候,我们的程序需要启动一些子进程,如嵌入的图形程序. 当启动一个进程后,获得这个进程信息Process,然后其内部在某个时刻启动了一个子进程,这个时候就涉及程序域和进程树的概念.当我们通过非正常操作的方式结束前面获得的进程信息Process时(如Kill掉),可能并没有实际结束子进程.因为当有主进程启动了子进程后,所有的进程实际上是被放在程序域中运行的(winform的Program文件中的Application域中),而结束的仅仅是域中的某个进程.当然,如果我们正常推出主进程,实际上App

  • C#操作windows系统进程的方法

    本文实例讲述了C#操作windows系统进程的方法.分享给大家供大家参考.具体如下: 这段代码演示了如何根据进程名关闭进程和启动进程 /// <summary> /// 关闭进程 /// </summary> private bool CloseProcess(string CloseProcessName) { try { //根据进程名称,获取该进程信息 Process[] MyProcessS = Process.GetProcessesByName(CloseProcess

随机推荐