С# проверить, существует ли процесс, затем закрыть его
Я пытаюсь закрыть процесс внутри С#, но как проверить, открыт ли он первым? Пользователи попросили эту функцию, и некоторые из них все еще будут использовать кнопку закрытия другого процесса.
Итак, сейчас отлично работает:
Process.GetProcessesByName("ProcessName")[0].CloseMainWindow();
Теперь, как сначала проверить, что он существует, это не работает:
if ( Process.GetProcessesByName("ProcessName")[0] != null ) {...}
Ответы
Ответ 1
Попробуйте это, чтобы избежать условия гонки, когда процесс завершается после первого вызова GetProcessesByName
:
Process[] processes = Process.GetProcessesByName("ProcessName");
if (processes.Length > 0)
processes[0].CloseMainWindow();
Ответ 2
Если вы планируете развернуть это приложение на широком спектре машин, вам нужно знать, что этот код может иногда терпеть неудачу.
Класс Process
в .NET основан на счетчиках производительности Windows, который на некоторых машинах можно отключить через реестр. Когда это произойдет, вызов метода Process.GetProcessesByName
вызовет исключение.
Я думаю, что эта ситуация характерна для машин с различными приложениями "очистки/настройки производительности", которые, помимо прочего, отключают счетчики производительности, чтобы якобы улучшить производительность машины.
В прошлом это неоднократно вызывало у меня боль с некоторым процентом клиентских машин моих клиентов, что заставило меня исследовать другие (хотя и несколько ограниченные или громоздкие) альтернативы, например, делать вызовы в Win API напрямую, используя PInvoke, для итерации по процессы.
Другим возможным решением было бы обеспечить, чтобы ваш установщик или приложение включали счетчики производительности или, по крайней мере, знали, как с ними бороться.
Ответ 3
Как насчет
if (Process.GetProcessesByName("ProcessName").Length > 0) {...}
Ответ 4
Вы также можете просто создать цикл, который отлично работает, если его нет.
foreach(Process p in Process.GetProcessesByName("ProcessName"))
{
p.CloseMainWindow();
}
Ответ 5
Process.GetProcessesByName("ProcessName").FirstOrDefault() != null