Я использую C# System.Diagnostic.Process
объект.
Одно из его свойств Id
.
Id
это продукты не является тем же как PID
, показанный в Windows Task Manager
.
Почему это?
Вы видите, после того как этот процесс запускается.
Это запускает два других неуправляемых процесса, для которых я не могу явно получить идентификаторы для ссылками свойства объекта.
Я должен перерыть все процессы для нахождения их именем процесса через System.Diagnostics.Process.GetProcesses()
.
Я пытаюсь найти надежный способ уничтожить этот процесс и все связанные процессы PID
, тот, который показывает в Task Manager
.
Существует ли лучший путь?
Я не могу только уничтожить все процессы со связанными именами процесса, потому что это могло бы уничтожить другие экземпляры тех процессов, которые не имеют никакого отношения к моей программе.
Ключ в том, что вы не хотите убивать свой процесс по Id. Фактически, это состояние гонки: порожденный вами процесс может умереть, а другой процесс может быть создан с тем же Id. Тогда, когда вы захотите убить его, вы в итоге убьете новый процесс вместо старого, который уже умер.
Самый надежный способ убить порожденные процессы - поместить их в объект Job и завершить Job, когда ваша задача будет выполнена.
Вот простой код для реализации класса Job:
class Job
{
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr CreateJobObject(IntPtr lpJobAttributes, string lpName);
[DllImport("kernel32.dll")]
public static extern bool AssignProcessToJobObject(IntPtr hJob, IntPtr hProcess);
[DllImport("kernel32.dll")]
public static extern bool TerminateJobObject(IntPtr hJob, uint uExitCode);
IntPtr job;
public Process StartProc(string commandLine)
{
if (job == IntPtr.Zero)
job = CreateJobObject(IntPtr.Zero, null);
ProcessStartInfo si = new ProcessStartInfo(@"c:\windows\system32\cmd.exe");
si.Arguments = "/c " + commandLine;
si.CreateNoWindow = false;
si.UseShellExecute = false;
Process proc = Process.Start(si);
AssignProcessToJobObject(job, proc.Handle);
return proc;
}
public void TerminateProc()
{
// terminate the Job object, which kills all processes within it
if (job != null)
TerminateJobObject(job, 0);
job = IntPtr.Zero;
}
}
Я не могу воспроизвести это. Я только что запустил следующий код:
foreach (var proc in Process.GetProcesses()
.OrderBy(proc => proc.Id))
{
Console.WriteLine("{0}: {1}", p.Id, p.ProcessName);
}
Все перечисленные процессы соответствуют PID в диспетчере задач. Используется Windows 7 - какую ОС вы используете? Если вы посмотрите на другие процессы, совпадут ли они с PID, указанным в диспетчере задач?