Содержание
Класс Process предоставляет доступ к локальным и удаленным процессам, а также позволяет запускать и останавливать локальные системные процессы. Этот класс удобно использовать в том случае, если Вам необходимо запустить какой-либо сторонний процесс (приложение) и получить от этого приложения данные.
Рассмотрим несколько примеров работы с классом Process.
Как в C# запустить стороннюю программу
Допустим, нам необходимо из своего консольного приложения на C# запустить «Блокнот» (notepad.exe). С классом Process это можно сделать следующим образом:
using System.Diagnostics;
namespace ConsoleApp2
{
internal class Program
{
static void Main(string[] args)
{
Console.ReadKey();
Process process = Process.Start("notepad.exe");
try
{
process.WaitForExit();
Console.WriteLine("Внешний процесс завершен");
}
finally
{
process.Dispose();
}
}
}
}
Вначале мы подключили пространство имен System.Diagnostics в котором содержится класс Process. Затем, приложение ожидает нажатия любой кнопки и запускает новый процесс notepad.exe, используя одну из версий статического метода Start.
Process process = Process.Start("notepad.exe");
Этот метод возвращает объект типа Process и, так как Process реализует интерфейс IDisposable, то мы должны прямо или косвенно освободить память и ресурсы используемые объектом после окончания его работы. Поэтому далее мы поместили код в блок try...finally для того, чтобы напрямую освободить ресурсы. Внутри блока мы ожидаем пока запущенный процесс не завершит свою работу:
process.WaitForExit();
Как только «Блокнот» будет закрыт, в консоль выведется сообщение о том. что внешний процесс завершил свою работу.
Как в C# открыть URL в браузере по умолчанию
Для того, чтобы открыть какой-либо URL в браузере по умолчанию достаточно сделать следующий вызов метода Start у класса Process:
using Process process = Process.Start("explorer", "https://csharp.webdelphi.ru");
здесь второй параметр метода — это аргументы командной строки с которыми запускается приложение. И далее, стоит рассмотреть ещё один более сложный пример — запуск приложения с параметрами.
Как в C# запустить стороннюю программу с параметрами
В предыдущих примерах мы не использовали ничего, кроме статического метода Start() у класса Process. Однако этот класс позволяет сделать более «тонкую» настройку запускаемого внешнего процесса.
Внешнее консольное приложение для запуска
Для демонстрации следующего примера я написал небольшое консольное приложение которое получает в параметрах два числа, перемножает их и выводит результат в консоль:
namespace Multiply
{
internal class Program
{
static void Main(string[] args)
{
if (args.Length < 2)
{
Console.Error.WriteLine("Ошибка: недостаточно данных для вычислений");
return;
}
if (int.TryParse(args[0], out int first) == false)
{
Console.Error.WriteLine("Ошибка: в первом параметре содержится не число");
return;
}
if (int.TryParse(args[1], out int second) == false)
{
Console.Error.WriteLine("Ошибка: во втором параметре содержится не число");
return;
}
Console.WriteLine($"{first * second}");
}
}
}
Само приложение я поместил в папку c:\temp\
Запуск стороннего приложения с параметрами
Чтобы запустить в C# стороннее приложение с параметрами мы можем создать экземпляр класс Process и настроить его свойства следующим образом:
using System.Diagnostics;
namespace ConsoleApp2
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
Console.ReadKey();
using Process process = new Process();
{
process.StartInfo.FileName = @"c:\temp\Multiply.exe"; //путь к приложению, которое будем запускать
process.StartInfo.WorkingDirectory = @"c:\temp\"; //путь к рабочей директории приложения
process.StartInfo.Arguments = "7 3"; //аргументы командной строки (параметры)
process.Start();
};
}
}
}
После запуска приложения мы увидим в консоли результат вычисления 7х3, то есть число 21. Рассмотрим другие полезные возможности использования класса Process.
Перенаправление стандартных потоков ввода/вывода внешнего приложения
Про перенаправление потоков ввода-вывода в консольных приложениях C# мы говорили здесь. Класс Process позволяет, при необходимости, перенаправить стандартные потоки ввода-вывода внешнего приложения в свой поток StandardOutput. Рассмотрим как это сделать, используя разработанное приложение для перемножения двух чисел. Наше приложение может не только перемножать числа, но и, при необходимости, выводить в консоль три типа ошибок: когда количество параметров недостаточно и когда один из параметров не является числом. Перепишем пример работы с Process, представленный выше так, чтобы вся информация о работе внешнего приложения выводилась в поток Process.StandardOutput:
using System.Diagnostics;
namespace ConsoleApp2
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
Console.ReadKey();
using Process process = new Process();
{
process.StartInfo.FileName = @"c:\temp\Multiply.exe";
process.StartInfo.WorkingDirectory = @"c:\temp\";
process.StartInfo.Arguments = "2 3";
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError= true;
process.OutputDataReceived += DataReceivedEventHandler; //обработчик события при получении очередной строки с данными
process.ErrorDataReceived += ErrorReceivedEventHandler; //обработчик события при получении ошибки
process.Start(); //запускаем процесс
process.BeginOutputReadLine(); //начинаем считывать данные из потока
process.BeginErrorReadLine(); //начинаем считывать данные об ошибках
process.WaitForExit(); //ожидаем окончания работы приложения, чтобы очистить буфер
process.Close(); //завершает процесс
};
}
static void DataReceivedEventHandler(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
Console.WriteLine($"Внешний процесс вернул данные: {e.Data}");
}
}
static void ErrorReceivedEventHandler(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
Console.WriteLine($"Внешний процесс вернул ошибку: {e.Data}");
}
}
}
}
Во-первых, мы создали и назначили два обработчика событий:
- Метод
DataReceivedEventHandler— обработчик события при поступлении в потокStandardOutputочередной строки с данными - Метод
ErrorReceivedEventHandler— обработчик события при возникновении ошибки.
Эти обработчики мы назначили соответствующим событиям класса Process:
process.OutputDataReceived += DataReceivedEventHandler; process.ErrorDataReceived += ErrorReceivedEventHandler;
Во-вторых, мы перенаправили стандартные потоки выводи и ошибок из внешнего приложения в наше:
process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError= true;
В-третьих, мы запустили операции чтения данных из потока вывода и потока ошибок:
process.BeginOutputReadLine(); process.BeginErrorReadLine();
Теперь можно запустить приложение и посмотреть на результат. Результат, когда в качестве аргумента для стороннего приложения задано не число:
Результат, когда заданы верные параметры:
Как можно видеть по результатам, обработчики события работают корректно, что говорит о том, что мы перенаправили стандартные потоки ввода-вывода из внешнего консольного приложения в наше.
Другие возможности класса Process
Класс Process не зря содержится в пространстве имен System.Diagnostics. Класс Process — это полезное средство не только для запуска, остановки и контроля внешних процессов, но и для их мониторинга.
Класс Process можно использовать для получения списка запущенных процессов.
Класс Process используется для доступа к системным процессам.
После инициализации Process его можно использовать для получения сведений о запущенном процессе. Эти сведения включают в себя набор потоков, загруженные модули (файлы .dll и .exe) и информацию о производительности, например объем памяти, используемой процессом.
Итого
Используя класс Process мы можем запускать сторонние приложения из C#, открывать различные документы и ссылки на ресурсы в приложениях по умолчанию, перенаправлять потоки ввода-вывода из внешних приложений в свои, а также, при необходимости, получать различную диагностическую информацию о процессах запущенных в операционной системе.