Как остановить процесс в C #, зная его имя файла? - PullRequest
6 голосов
/ 13 марта 2012

У меня есть программа, которая запускает другую (давайте назовем первое приложение Stater, а второе приложение - Worker).

Я использую

process.start();
process.waiForExit();
process.Close();

в Starter.

Но если Starter принудительно закрывается в ожидании Worker (по какой-то внешней причине), Worker все еще находится в процессе, блокируя файлы, потребляя память и т. Д.

Итак, я хочу проверить, работает ли Worker, прежде чем я попытаюсь запустить его. Я пробовал Process.GetProcessesByName ("worker.exe"), но не повезло (даже если я вижу Worker в диспетчере задач).

Я видел здесь несколько тем о проверке каждого процесса в памяти на наличие его модулей, но все же я уже знаю исполняемый файл, и надеюсь избежать такого решения.

Есть советы?

Ответы [ 5 ]

16 голосов
/ 13 марта 2012

Причина, по которой вы не можете его найти, заключается в том, что вы используете .exe.Если исполняемый файл отображается как Task.exe в TaskManager, просто вызовите:

Process[] workers = Process.GetProcessesByName("worker")
foreach (Process worker in workers)
{
     worker.Kill();
     worker.WaitForExit();
     worker.Dispose();
}
6 голосов
/ 13 марта 2012

Во время запуска процесса Worker сохраните его идентификатор в файле конфигурации / настройки вашего приложения. Таким образом, при запуске процесса Starter он сначала загрузит этот идентификатор из файла настроек и проверит, находится ли этот процесс в данный момент. работает или нет. Если вы хотите немедленно закрыть рабочий процесс, вы можете вызвать process.Kill() для него.

4 голосов
/ 01 декабря 2013

Это намного проще ...

System.Diagnostics.Process.Start("cmd.exe","/c taskkill /IM notepad.exe");

Этот код закроет Блокнот (если он запущен). Введите имя программы, которую вы хотите закрыть, с ее расширением (.exe).

Некоторые приложения не могут быть остановлены без форсирования. Используйте /F после taskkill, чтобы форсировать действие. Если вы хотите закрыть дерево процессов, используйте /T после имени программы.

System.Diagnostics.Process.Start("cmd.exe","/c taskkill /F /IM notepad.exe /T");
2 голосов
/ 13 марта 2012

Если вам нужно только обнаружить , что "рабочий" работает, технически намного превосходящее решение - это заблокировать глобальный мьютекс на время его существования.Любой процесс, который знает имя мьютекса (которое находится под вашим контролем), может затем увидеть, заблокирован ли мьютекс (если он работает, рабочий).

Однако это нелегко реализовать правильно так как есть много мелких деталей, которые вы хотите получить правильно;даже в этом случае может быть условие состязания, когда «стартер» и «рабочий» фактически запускаются одновременно и т. д. (конечно, эта проблема и многие другие также применимы ко всем остальным решениям, поэтому ее нельзя считать недостатком).

2 голосов
/ 13 марта 2012

Когда вы вызываете GetProcessesByName ("worker") , вы не указываете расширение exe, как описано в MSDN
И если вы хотите сохранить глобальную переменную в запущенном объекте процесса, вы можете просто использовать process.Kill ();

...