Данная статья описывает создание программы запуска «инсталляционных» файлов и отслеживание завершения, как основного, так и дочерних процессов создаваемых основным.
Создайте приложение «Windows Form» в «Microsoft Visual Studio». Добавьте на главную форму созданного проекта, следующие элементы управления:
- Button button1 – кнопка запуска выбранного файла;
- ListBox listBox1 – лог отображения выполнения процессов;
- Label label1 – обозначение текстового поля содержащего путь к исполняемому файлу;
- Label label2 – обозначение текстового поля содержащего необходимые аргументы для запуска исполняемого файла;
- TextBox textBox1 – текстовое поле, для ввода пути к исполняемому файлу;
- TextBox textBox2 – текстовое поле, для ввода аргументов необходимых для запуска исполняемого файла;
- BackgroundWorker backgroundWorker1 – компонент необходимый для запуска исполняемого файла с аргументами и отслеживания завершения как основного так и дочерних процессов в отдельном потоке.
Выполните двойной клик правой клавишей мыши по элементу управления «button1». Вы перейдете в редактор кода с автоматически созданным методом «button1_Click». Добавьте в него приведенный ниже код блокировки кнопки «Запуск» и запуска исполняемого файла с аргументами и отслеживания завершения, как основного, так и дочерних процессов в отдельном потоке.
//Блокируем кнопку запуска исполняемого файла. button1.Enabled = false; //Запускаем выполнение фоновой операции. backgroundWorker1.RunWorkerAsync();Перейдите в графический редактор главной формы вашего проекта и откройте события доступные для компонента «backgroundWorker1». Выполните двойной клик по событиям «DoWork» и «RunWorkerCompleted».
Ниже приведен код метода «backgroundWorker1_DoWork».
//Переменная для определения результата работы //программы. bool reseult_install = false; private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { reseult_install = StartInstall(textBox1.Text, textBox2.Text); }Так же, код для метода «backgroundWorker1_RunWorkerCompleted».
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (reseult_install== true) debug("Работа процесса завершена успешно!"); else debug("Работа процесса завершена с ошибками."); //Работа программы завершена, выполняем разблокировку //кнопки запуска. button1.Enabled = true; }Добавьте в листинг главной формы вашего проекта, приведенный ниже код, метода запуска и отслеживания завершения процесса.
private bool StartInstall(string FileSetup, string Arguments) { //Переменная с результатом выполнения программы. bool result = false; try { //Инициализируем новый экземпляр класса System.Diagnostics.Process. Process StartProcess = new Process(); //Инициализируем новый экземпляр класса System.Diagnostics.ProcessStartInfo //и задаем аргументы, вместе с которыми должен //запускаться процесс. ProcessStartInfo startInfo = new ProcessStartInfo(FileSetup); //Задаем набор аргументов командной строки, // используемых при запуске приложения. if (Arguments != null || Arguments.Length > 0) startInfo.Arguments = Arguments; //Задаем свойства для передачи их методу System.Diagnostics.Process.Start() //объекта System.Diagnostics.Process. StartProcess.StartInfo = startInfo; //Запускаем (или начинаем заново использовать) ресурс процесса, определенный //свойством System.Diagnostics.Process.StartInfo //этого компонента System.Diagnostics.Process. StartProcess.Start(); //Выводим информацию о работе программы debug("Успешный запуск процесса"); debug("Имя процесса: "+StartProcess.ProcessName); debug("Идентификатор: "+StartProcess.Id); //Даем System.Diagnostics.Process команду ожидать неопределенно //долго до завершения связанного процесса. StartProcess.WaitForExit(); debug("Основной процесс завершён!"); //Получаем значение, определяющее завершение связанного процесса. if (StartProcess.HasExited) { result = true; debug("Связанный процесс завершён!"); } else result = false; try { debug("Поиск дочерних процессов для " + StartProcess.Id); //Запускаем процесс отслеживания дочерних процессов. WaitAllProcesses((UInt32)StartProcess.Id); } catch (Exception ex) { debug("Ошибка поиска дочерних процессов..."); //В случае возникновения ошибки, выводим ее в лог. debug(ex.Message); result = false; } } catch (Exception ex) { result = false; } return result; } private void WaitAllProcesses(UInt32 parentProcessId) { debug(String.Format("Поиск дочерних процессов [{0}]", parentProcessId)); //Выполняем поиск процессов с указанием идентификатора процесса, //породившего данный процесс. ManagementObjectSearcher searcher = new ManagementObjectSearcher( String.Format("SELECT * FROM Win32_Process WHERE ParentProcessId={0}", parentProcessId)); //Вызываем заданный WMI-запрос и получаем результирующую коллекцию. ManagementObjectCollection collection = searcher.Get(); //Если найдены дочерние процессы, то идем дальше. if (collection.Count > 0) { debug(String.Format("Найдено {0} дочерних процессов", collection.Count)); debug(String.Format("главного процесса с идентификатором [{0}]", parentProcessId)); //Выполняем проход по всей коллекции. foreach (var item in collection) { //Получаем индентификатор текущего дочернего процесса. UInt32 childProcessId = (UInt32)item["ProcessId"]; if ((int)childProcessId != Process.GetCurrentProcess().Id) { //Запускаем поиск дочерних процессов для текущего //дочернего процесса. WaitAllProcesses(childProcessId); //Получаем новый компонент System.Diagnostics.Process, c заданным //идентификатором процесса на локальном компьютере. Process childProcess = Process.GetProcessById((int)childProcessId); debug(String.Format("Ожидание дочернего процесса [{0}]", childProcess.ProcessName)); debug(String.Format("с идентификатором [{0}]", childProcessId)); //Даем System.Diagnostics.Process команду ожидать неопределенно //долго до завершения связанного процесса. childProcess.WaitForExit(); } } } } //Так как отслеживание завершения процесса будет //выполняться в другом потоке, то для доступа к логу //необходимо выполнить указанный делегат асинхронно в потоке, //в котором был создан базовый дескриптор //элемента управления. public void debug(string text) { try { if (this.InvokeRequired) BeginInvoke(new MethodInvoker(delegate { listBox1.Items.Add(String.Format("[{0}] {1}", DateTime.Now, text)); })); else { listBox1.Items.Add(String.Format("[{0}] {1}", DateTime.Now, text)); } } catch (Exception ex) { listBox1.Items.Add(String.Format("[{0}] {1}", DateTime.Now, ex.Message)); } }Запустите проект, укажите путь к исполняемому файлу и аргументы при необходимости. Нажмите кнопку «Запуск» и отслеживайте изменения в логе программы.
Комментариев нет:
Отправить комментарий
Большая просьба, не писать в комментариях всякую ерунду не по теме!