En C #, cómo matar un árbol de procesos de manera confiable [duplicar]
Frecuentes
Visto 5,363 equipos
5
In C#, we use the following code to kill a process tree. Sometimes it works, and sometimes it doesn't, possibly having to do with Windows 7 and/or 64-bit.
The way it finds children of the given process is by calling GetProcesses
to get all the processes in the system, and then calling NtQueryInformationProcess
to find out every process whose parent is the given process.
It does this recursively, to walk the tree.
The on-line doc says NtQueryInformationProcess
should not be used.
Instead there is something called EnumProcesses
, but I can't find any examples in C#, only other languages.
What's a reliable way to kill a tree of processes in C#?
public static void TerminateProcessTree(Process process)
{
IntPtr processHandle = process.Handle;
uint processId = (uint)process.Id;
// Retrieve all processes on the system
Process[] processes = Process.GetProcesses();
foreach (Process proc in processes)
{
// Get some basic information about the process
PROCESS_BASIC_INFORMATION procInfo = new PROCESS_BASIC_INFORMATION();
try
{
uint bytesWritten;
Win32Api.NtQueryInformationProcess(proc.Handle, 0, ref procInfo,
(uint)Marshal.SizeOf(procInfo), out bytesWritten); // == 0 is OK
// Is it a child process of the process we're trying to terminate?
if (procInfo.InheritedFromUniqueProcessId == processId)
{
// Terminate the child process (and its child processes)
// by calling this method recursively
TerminateProcessTree(proc);
}
}
catch (Exception /* ex */)
{
// Ignore, most likely 'Access Denied'
}
}
// Finally, terminate the process itself:
if (!process.HasExited)
{
try
{
process.Kill();
}
catch { }
}
}
1 Respuestas
9
Utilice la herramienta ManagmentObjectSearcher
and a little recursion:
private 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);
proc.Kill();
}
catch (ArgumentException)
{
// Process already exited.
}
}
contestado el 24 de mayo de 14 a las 14:05
Excuse my naivete', but I tried using System.Management;
and that didn't seem to give me access to it. I must be missing something. - mike dunlavey
Did you add a reference to System.Management.dll
? - Yuval Itzchakov
Wouldn't you want to kill the parent process first to avoid it restarting processes? - austin salgat
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas c# process or haz tu propia pregunta.
Realizar el equivalente de "Kill Process Tree" en c ++ en Windows (clearly you already know how to P/Invoke) - Cody Gray
Your question reduces to "How to find all child processes". Killing them is a trivial extension of the problem. This is therefore a duplicate. - usr
@usr: Thanks for flagging that. I'm still trying to figure out what
using
statement to use. - Mike Dunlavey@MikeDunlavey not sure what you mean. Sounds like a simple research task, whatever it is. If you can't do it, ask a new question. - usr
Uhh, the question I linked is a Manera better choice if we're closing this as a duplicate. But I specifically didn't vote to close, because it isn't an exact duplicate of either question. For one thing, it uses a different language. Even if translating the code is trivial, it's not a duplicate. (Mike, I don't know what you mean either by trying to figure out what
using
statement to use. Is that your way of saying you're hopelessly lost? If you're completely new to .NET, you might want to mention that. I made some assumptions looking at your rep. ;-)) - Cody Gray