Добрый день друзья, сегодня я расскажу, как можно использовать стандартный вывод запускаемого консольного приложения.
Существует еще достаточно большое количество приложений, у которых нет окон и «кнопочного» интерфейса. Все, что выводят на экран – это простой текст, который даже скопировать не всегда можно. Брать переписывать все консольные приложения нет смысла, тем более что автор уже все за вас написал. Если вам нужно использовать консольную программу, но не хочется видеть на экране консоль, тогда можно написать свою оболочку GUI (графический интерфейс пользователя). Эта оболочка должна в фоновом режиме запускать консольное приложение, управлять им и получать результаты работы.
Давайте создадим два проекта. Один из них будет консольным приложением, другой основанный на Windows Form.
1. В Visual Studio создайте новое Console Application и вставьте следующий код в область метода Main. Добавим пару методов, которые выводят текстовую информацию на экран. Проверьте приложение на работоспособность.
1 |
static void Main(string[] args) |
3 |
string command = string.Empty; |
11 |
case "-ver": version(); |
13 |
default: Console.WriteLine("Аргумент " + args[0] + " не используется!"); |
20 |
command = Console.ReadLine(); |
21 |
switch (command.ToLower()) |
25 |
case "ver": version(); |
32 |
private static void view() |
34 |
Console.WriteLine(string.Format("{0,-26}:{1}", "Имя текущего пользователя", Environment.UserName)); |
35 |
Console.WriteLine(string.Format("{0,-26}:{1}", "Версия ОС", Environment.OSVersion)); |
36 |
Console.WriteLine(string.Format("{0,-26}:{1}", "Имя компьютера", Environment.MachineName)); |
39 |
private static void version() |
41 |
Console.ForegroundColor = ConsoleColor.Green; |
42 |
Console.WriteLine(string.Format("{0,-26}:{1}", "Текущая версия .NET", Environment.Version)); |
43 |
Console.ForegroundColor = ConsoleColor.White; |
2. Создайте новое Windows Form приложение, в котором мы реализуем функции работы с консольным приложением.
Для реализации задуманного, нам понадобиться реализовать три метода.
Первый метод будет запускать внешнюю программу и инициализировать перехват данных. Код метода Run:
1 |
private void run(string utilityName, string arguments) |
10 |
pr.StartInfo.FileName = utilityName; |
12 |
pr.StartInfo.Arguments = arguments; |
14 |
pr.StartInfo.UseShellExecute = false; |
16 |
pr.StartInfo.RedirectStandardOutput = true; |
18 |
pr.StartInfo.StandardOutputEncoding = Encoding.GetEncoding(866); |
20 |
pr.StartInfo.CreateNoWindow = true; |
22 |
pr.OutputDataReceived += new DataReceivedEventHandler(sortOutputHandler); |
24 |
pr.EnableRaisingEvents = true; |
26 |
pr.Exited += new EventHandler(whenExitProcess); |
30 |
pr.BeginOutputReadLine(); |
32 |
catch (Exception error) |
34 |
MessageBox.Show("Ошибка при запуске!\n" + error.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); |
Порядок выполнения описан в комментариях. Для правильной работы с русскими сим-волами вы должны всегда использовать строку pr.StartInfo.StandardOutputEncoding = Encoding.GetEncoding(866), которая правильно задает кодировку выходного потока. Следует помнить, что pr.Start() автоматически запускает внешнее приложение в отдельном потоке.
Второй и третий методы, это функции для событий получения данных и завершения работы приложения.
1 |
private void sortOutputHandler(object sendingProcess, DataReceivedEventArgs outLine) |
4 |
BeginInvoke(new MethodInvoker(delegate |
6 |
if (!String.IsNullOrEmpty(outLine.Data)) |
9 |
txtOutput.AppendText(outLine.Data + Environment.NewLine); |
14 |
private void whenExitProcess(Object sender, EventArgs e) |
16 |
BeginInvoke(new MethodInvoker(delegate |
18 |
txtOutput.AppendText("Программа завершила свою работу!"); |
BeginInvoke(new MethodInvoker(delegate… позволяет получить доступ к элементу интерфейса из другого потока.
Метод run вызывается следующим образом:
1 |
run(Path.Combine(Application.StartupPath, "test.exe"), "-view"); |
После завершения работы, скопируйте файл test.exe в папку со вторым приложением. Вот что у нас получилось:
1 run(Path.Combine(Application.StartupPath, "test.exe"), "-view");
После завершения работы, скопируйте файл test.exe в папку со вторым приложением. Вот что у нас получилось:

Бонус:
Функция перекодировки из DOS в UTF:
2 |
/// Перекодировка из dos в UTF8 |
4 |
/// <param name="src"></param> |
5 |
/// <returns></returns> |
6 |
private string DosToUtf(string src) |
11 |
Encoding dos866 = Encoding.GetEncoding(866); |
13 |
byte[] srcBytes = dos866.GetBytes(src); |
15 |
byte[] dstBytes = Encoding.Convert(dos866, UTF8Encoding.UTF8, srcBytes); |
17 |
string source = UTF8Encoding.UTF8.GetString(dstBytes); |
20 |
catch (Exception error) |
22 |
MessageBox.Show(error.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); |
Заключение
Разобрали как запустить внешнее приложение.
Как из него читать выходные данные.
Как определить завершение внешнего приложения.
Этим все не ограничивается. Разработчику также доступны функции RedirectStandardError и RedirectStandardInput, соответственно для перехвата ошибок и отправки данных внешнему приложению.
Единственно, что нельзя сделать – подключиться с стандартному выводу приложения, которое уже было запущено до нас.