Данная статья описывает создание программы запуска «инсталляционных» файлов и отслеживание завершения, как основного, так и дочерних процессов создаваемых основным.
Создайте приложение «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));
}
} Запустите проект, укажите путь к исполняемому файлу и аргументы при необходимости. Нажмите кнопку «Запуск» и отслеживайте изменения в логе программы.




Комментариев нет:
Отправить комментарий
Большая просьба, не писать в комментариях всякую ерунду не по теме!