C# Windows Forms: запускаем и завершаем внешние приложения
Формально проблема несложна - подключив к проекту пространство имён
using System.Diagnostics;
мы можем запускать внешние приложения кодом вида
Process p = Process.Start("notepad.exe");
(в данном случае файл находится в одной из прописанных в системной переменной Path папок, поэтому указываем только имя исполняемого файла) и завершать его строкой
p.CloseMainWindow();
Увы, это не решает как минимум следующих проблем:
- метод
CloseMainWindowне гарантирует, что приложение действительно закрыто или что процесс завершился, а лишь информирует, что отправлено сообщение закрытия основному окну процесса; - одноимённых процессов может быть несколько или не быть вовсе;
- имя процесса (оно видно, например, на вкладке "Подробности" Диспетчера задач Windows 10) может отличаться от имени исполняемого файла (например, для стандартного калькулятора запускается процесс
CalculatorApp, а имя файлаcalc.exe, хотя обычно имя процесса - это имя исполняемого файла без расширения, то есть,notepadдляnotepad.exe); - процесс может просто запускать другой процесс с другим идентификатором, а сам завершаться, как делает тот же Калькулятор;
- процесс может быть закрыт независимо от работы приложения, пока оно остаётся запущенным, при этом он должен удаляться из списка запущенных нами процессов (установить
EnableRaisingEvents = trueи обработку событияExited); - по неизвестным причинам MainWindowHandle у процесса может оказываться нулём и тогда
CloseMainWindowне срабатывает, а завершить процесс программно можно разве что черезKill(принудительное завершение без сохранения данных); - вызов
Killтоже может порождать исключения, например, если не хватает прав или система не успевает обработать завершение; - во всех случаях имеет смысл подождать закрытия окна методом
WaitForExit; - при массовом закрытии процессов в цикле отсутствие паузы между закрытиями может стать причиной ошибок, таких как
System.ComponentModel.Win32Exception, например, если процесс еще не завершился, а мы пытаемся его принудительно убить или послать ему закрытие.
В прилагаем проекте мы пытаемся учесть все эти моменты с помощью нескольких методов:
void process_Run (string filePath, string appName)- создаёт процесс вызовомprocess_Start, создаёт объектprocessInfoдля процесса и заносит объект в списокList <ProcessInfo> processes;Process process_Start (String filePath)- открывает и возвращает процесс илиnull;void process_End (ProcessInfo process)- для закрытия процесса, информация о котором сохранена в объекте пользовательского классаProcessInfo, содержащего свойстваstring FilePath,string AppName,Process Process;void process_Stop (String appName)- ищет последний по времени запуска процесс с именемappNameи вызывает для негоprocess_End. Отдельно отслеживается ситуация, когда процесс не был нами запущен и не попал в наш список (например, был запущен до старта программы).
Эти методы применяются для открытия и закрытия произвольного количества стандартных приложений Калькулятор, Блокнот и Paint по принципу:
process_Run ("calc.exe", "CalculatorApp");
process_Run ("notepad.exe", "notepad");
//...
process_Stop("CalculatorApp");
process_Stop("notepad");
Методы выводят текстовые сообщения в многострочное поле textBox1, занимающее основную часть окна.
При выходе из приложения через меню Файл - Выход закрываются те экземпляры указанных приложений, которые мы открывали.
Существенно, что экземпляров Калькулятора к моменту выхода через меню в нашем списке уже не окажется, так как calc.exe запускает CalculatorApp.exe, который, в свою очередь, его завершает. Но для большинства приложений (в том числе для двух других тестовых) этой проблемы не возникает. Зато через меню Файл - Имя приложения - Стоп можно закрыть и те экземпляры приложений, которые мы не запускали, без вылета, если закрытие не удаётся (например, для экземпляра Калькулятора, часто запускаемого системой и болтающегося в процессах - у пользователя нет возможности его закрыть иначе, как сняв через Диспетчер задач с правами администратора).
Вывод - подход работает для "обычных" приложений, не ведущих себя так, как Калькулятор Windows.
скриншот окна приложения
Скачать проект C# Windows Forms в архиве .zip, развернуть в новую папку (Visual Studio 2019 и выше) (13 Кб)
13.01.2026, 00:10 [287 просмотров]

