/// <summary> /// Terminate a process tree /// </summary> /// <param name="hProcess">The handle of the process</param> /// <param name="processID">The ID of the process. Passed as UInt64 to make sure it works in both 32- and 64-bit environments</param> /// <param name="exitCode">The exit code of the process</param> public void TerminateProcessTree(IntPtr hProcess, UInt64 processID, int exitCode) { Process[] processes = Process.GetProcesses(); // Retrieve all processes on the system foreach (Process p in processes) { try { // Get some basic information about the process if (IntPtr.Size == 4) { // 32-bit PROCESS_BASIC_INFORMATION_32 pbi = new PROCESS_BASIC_INFORMATION_32(); uint bytesWritten; NtQueryInformationProcess32(p.Handle, 0, ref pbi, Marshal.SizeOf(pbi), out bytesWritten); // == 0 is OK // Is it a child process of the process we're trying to terminate? if (pbi.InheritedFromUniqueProcessId == processID) { // The terminate the child process and its child processes TerminateProcessTree(p.Handle, pbi.UniqueProcessId, exitCode); } } else { // 64-bit PROCESS_BASIC_INFORMATION_64 pbi = new PROCESS_BASIC_INFORMATION_64(); uint bytesWritten; NtQueryInformationProcess64(p.Handle, 0, ref pbi, Marshal.SizeOf(pbi), out bytesWritten); // == 0 is OK // Is it a child process of the process we're trying to terminate? if (pbi.InheritedFromUniqueProcessId == processID) { // The terminate the child process and its child processes TerminateProcessTree(p.Handle, pbi.UniqueProcessId, exitCode); } } } catch (Exception /* ex */) { // Ignore, most likely 'Access Denied' } } // Finally, termine the process itself: TerminateProcess(hProcess, exitCode); }
static extern int NtQueryInformationProcess64(IntPtr hProcess, int processInformationClass /* 0 */, ref PROCESS_BASIC_INFORMATION_64 processBasicInformation, int processInformationLength, out uint returnLength);