C#結(jié)束進(jìn)程及子進(jìn)程
這是個(gè)我在C#調(diào)用批處理文件時(shí)遇到的問(wèn)題。首先我通過(guò)Process.Start方法調(diào)用一個(gè)批處理文件,那個(gè)批處理文件里面則調(diào)用了一大堆程序。當(dāng)退出C#程序時(shí),我在程序中結(jié)束殺掉了那個(gè)批處理文件的Process,但是,那個(gè)批處理所調(diào)用的子進(jìn)程卻無(wú)法像直接調(diào)用批處理文件那樣隨著批處理文件的進(jìn)程一起被殺掉,而是自動(dòng)向上提升成為了獨(dú)立的進(jìn)程。
在網(wǎng)上查了一下,可以通過(guò)NtQueryInformationProcess函數(shù)查詢子進(jìn)程的信息,并同時(shí)也查到了一段殺掉進(jìn)程及所有子進(jìn)程的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:今天發(fā)現(xiàn)NtQueryInformationProcess函數(shù)在x64位程序上運(yùn)行無(wú)效, 具體原因不明,Google了一下也沒(méi)有找到答案,反而找到了另一種解決方案,通過(guò)WMI來(lái)實(shí)現(xiàn)的。在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 */ } }
到此這篇關(guān)于C#結(jié)束進(jìn)程及子進(jìn)程的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 如何在C# 中查找或結(jié)束程序域中的主、子進(jìn)程
- C#操作windows系統(tǒng)進(jìn)程的方法
- C#操作進(jìn)程的方法介紹
- C#獲取所有進(jìn)程的方法
- C#中進(jìn)程的掛起與恢復(fù)
- C#實(shí)現(xiàn)啟動(dòng),關(guān)閉與查找進(jìn)程的方法
- C#實(shí)現(xiàn)關(guān)閉其他程序窗口或進(jìn)程代碼分享
- C#實(shí)現(xiàn)強(qiáng)制關(guān)閉當(dāng)前程序進(jìn)程
- C#關(guān)閉指定名字進(jìn)程的方法
- C#實(shí)現(xiàn)查殺本地與遠(yuǎn)程進(jìn)程的方法
- C#操作windows系統(tǒng)進(jìn)程的方法
相關(guān)文章
C#使用命名管道Pipe進(jìn)行進(jìn)程通信實(shí)例詳解
這篇文章主要介紹了C#使用命名管道Pipe進(jìn)行進(jìn)程通信實(shí)例詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12詳解C#如何實(shí)現(xiàn)一個(gè)安全的事件訂閱器
事件訂閱器是一個(gè)對(duì)象,它訂閱(或監(jiān)聽(tīng))某個(gè)事件,并在事件發(fā)生時(shí)執(zhí)行相應(yīng)的操作,本文主要介紹了C#實(shí)現(xiàn)一個(gè)安全的事件訂閱器的相關(guān)知識(shí),感興趣的可以了解下2024-01-01C#實(shí)現(xiàn)的簡(jiǎn)單隨機(jī)數(shù)產(chǎn)生器功能示例
這篇文章主要介紹了C#實(shí)現(xiàn)的簡(jiǎn)單隨機(jī)數(shù)產(chǎn)生器功能,涉及C#簡(jiǎn)單界面布局、事件響應(yīng)及隨機(jī)數(shù)生成相關(guān)操作技巧,需要的朋友可以參考下2017-09-09C#操作DataGridView獲取或設(shè)置當(dāng)前單元格的內(nèi)容
這篇文章介紹了C#操作DataGridView獲取或設(shè)置當(dāng)前單元格的內(nèi)容,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-02-02C#實(shí)現(xiàn)Word轉(zhuǎn)換TXT的方法詳解
這篇文章主要為大家詳細(xì)介紹了如何利用C#實(shí)現(xiàn)Word轉(zhuǎn)換TXT的功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下2022-12-12C#連接SQL Server的實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于C#連接SQL Server的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-12-12