С# проверить, существует ли процесс, затем закрыть его

Я пытаюсь закрыть процесс внутри С#, но как проверить, открыт ли он первым? Пользователи попросили эту функцию, и некоторые из них все еще будут использовать кнопку закрытия другого процесса.

Итак, сейчас отлично работает:

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