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:今天發(fā)現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#結束進程及子進程的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持腳本之家。