По умолчанию исходная папка JNI называется jni. Переименование его в cpp исправило проблему
Это очень сработало для меня:
/// <summary>
/// Kill a process, and all of its children, grandchildren, etc.
/// </summary>
/// <param name="pid">Process ID.</param>
private static void KillProcessAndChildren(int pid)
{
// Cannot close 'system idle process'.
if (pid == 0)
{
return;
}
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.
}
}
Протестировано на Visual Studio 2015 Update 2
в Win7 x64
.
Добавлена проверка процесса простоя системы if (pid == 0)
Нужно добавить ссылку на пространство имен System.Management
, см. Комментарий от @MinimalTech ниже. Если у вас установлен ReSharper, он предложит вам сделать это автоматически.
Если кому-то понадобится ядро dotnet, dotnet cli разработал реализацию на основе taskill, как упоминалось выше, и рекурсивный pgrep / kill для систем на основе unix. Полная реализация может быть найдена на github . К сожалению, класс является внутренним, поэтому вам придется скопировать его в свою базу кода.
Список дочерних процессов (необходимо выполнить рекурсивно):
$"pgrep -P {parentId}"
Убить по процессу :
$"kill -TERM {processId}"
Как правильно закрыть Internet Explorer при запуске из PowerShell?
Некоторые из тех, кто прокомментировал этот поток, вызвали ошибку в Win7 (так как это не похоже, для пользователей, которые используют другие версии окон). Многие страницы в Интернете, в том числе ошибки пользователя на странице Microsoft, указывают, что вы просто используете доступный метод quit для IE-объекта, который SUPPOSED также закрывает все дочерние процессы (и, как сообщается, это делает в Win8 / XP и т. Д.)
Должен признать, со своей стороны, это ошибка пользователя WAS. Я нахожусь в win7, и причина, по которой метод quit не работал для меня, был из-за ошибки в кодировании. А именно, я создавал объект IE при объявлении, а затем создавал другой (прикрепленный к тому же объекту) позже в коде ... Я почти закончил взломать процедуру убийства родительского ребенка, чтобы работать на меня, когда я понял проблему.
Из-за того, как IE функционирует, идентификатор processID, который вы породили, поскольку родительский объект может быть прикреплен к другим окнам / подпроцессам, которые вы НЕ создали. Используйте quit и помните, что в зависимости от пользовательских настроек (например, пустой кеш при выходе) для завершения процессов и закрытия их может потребоваться несколько минут.
Другое решение - использовать команду taskill. Я использую следующий код в своих приложениях:
public static void Kill()
{
try
{
ProcessStartInfo processStartInfo = new ProcessStartInfo("taskkill", "/F /T /IM your_parent_process_to_kill.exe")
{
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = true,
UseShellExecute = false,
WorkingDirectory = System.AppDomain.CurrentDomain.BaseDirectory,
RedirectStandardOutput = true,
RedirectStandardError = true
};
Process.Start(processStartInfo);
}
catch { }
}
Я не поклонник каких-либо решений, представленных здесь.
Вот что я придумал:
private static void EndProcessTree(string imageName)
{
Process.Start(new ProcessStartInfo
{
FileName = "taskkill",
Arguments = $"/im {imageName} /f /t",
CreateNoWindow = true,
UseShellExecute = false
}).WaitForExit();
}
Как использовать:
EndProcessTree("chrome.exe");
Вы должны вызвать Process.CloseMainWindow()
, который отправит сообщение в главное окно процесса. Подумайте об этом как о том, чтобы пользователь нажал кнопку закрытия «X» или File | Выйти из пункта .
Безопаснее отправлять сообщение в Internet Explorer, чтобы закрыть его, а не идти и убивать все его процессы. Эти процессы могут что-то делать, и вы должны позволить IE сделать свое дело и закончить, прежде чем просто убить его в середине того, что может быть важным для будущих прогонов. Это верно для любой программы, которую вы убиваете.
Если кто-то заинтересован, я взял один из ответов с другой страницы и немного изменил его. Теперь это самостоятельный класс со статическими методами. Он не имеет правильную обработку ошибок или протоколирование. Модифицируйте, чтобы использовать для своих нужд. Предоставление вашего корневого процесса KillProcessTree сделает это.
class ProcessUtilities
{
public static void KillProcessTree(Process root)
{
if (root != null)
{
var list = new List<Process>();
GetProcessAndChildren(Process.GetProcesses(), root, list, 1);
foreach (Process p in list)
{
try
{
p.Kill();
}
catch (Exception ex)
{
//Log error?
}
}
}
}
private static int GetParentProcessId(Process p)
{
int parentId = 0;
try
{
ManagementObject mo = new ManagementObject("win32_process.handle='" + p.Id + "'");
mo.Get();
parentId = Convert.ToInt32(mo["ParentProcessId"]);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
parentId = 0;
}
return parentId;
}
private static void GetProcessAndChildren(Process[] plist, Process parent, List<Process> output, int indent)
{
foreach (Process p in plist)
{
if (GetParentProcessId(p) == parent.Id)
{
GetProcessAndChildren(plist, p, output, indent + 1);
}
}
output.Add(parent);
}
}
E_ACCESSDENIED
при перечислении процессов? – Mygod 17 January 2017 в 17:21