Консольный вывод. Читаем посимвольно.
Ранее в статье Читаем стандартный вывод консольного приложения + DOS to UTF я писал как подключаться и читать стандартный вывод консольных приложений. Все это конечно работает хорошо, но есть один нюанс — событие на которое мы подписываемся (pr.OutputDataReceived += new DataReceivedEventHandler(sortOutputHandler)) возникает только тогда, когда в консольной программе происходит переход на новую строку. В этот момент нам возвращается весь буфер строки. А так, как в одной строке можно вывести кучу информации используя, например, служебный символ \b (backspace), то для чтения текста из консоли код из предыдущей статьи может и не подойти.
На помощь приходит следующее решение. Мы создаем свой поток и подключаем к нему стандартный вывод консоли. Далее мы просто читаем наш поток и разбираем его.
В следующем коде используются переменные:
sr — наш поток, с которым мы работаем.
nsize — количество символов, которые будут читаться за раз.
buffer — массив в котором будут храниться кода символов. Сюда входят и служебные символы — переход на другую строку, backspace, tab и т.д.
sOut — ассинхронный вызов. В данном случае служит как заглушка.
В итоге получаем следующий код.
private void run(string utilityName, string arguments)
{
try
{
Stream sr; //поток из которого будем читать вывод консоли
int nsize = 5; //по сколько символов за раз будем читать. Можно установить и больше, и меньше
Byte[] buffer = new Byte[nsize]; //здесь то? что будем читать - размер количество символов
AsyncCallback sOut = new AsyncCallback(Res); //ассинхронный вызов
//создаем новый процесс, который будет работать с консолью
Process pr = new Process();
//задаем имя запускного файла
pr.StartInfo.FileName = utilityName;
//задаем аргументы для этого файла
pr.StartInfo.Arguments = arguments;
//отключаем использование оболочки, чтобы можно было читать данные вывода
pr.StartInfo.UseShellExecute = false;
//перенаправляем данные вовода
pr.StartInfo.RedirectStandardOutput = true;
//задаем кодировку, чтобы читать кириллические символы
pr.StartInfo.StandardOutputEncoding = Encoding.GetEncoding(866);
//запрещаем создавать окно для запускаемой программы
pr.StartInfo.CreateNoWindow = true;
//включаем возможность определять когда происходит выход из программы, которую будем запускать
pr.EnableRaisingEvents = true;
//подписываемся на событие, когда процесс завершит работу
pr.Exited += new EventHandler(whenExitProcess);
//запускаем процесс
pr.Start();
sr = pr.StandardOutput.BaseStream; //перенаправляем стандартный вывод в наш поток
sr.BeginRead(buffer, 0, nsize, sOut, null); //начинаем читать стандартный вывод консоли
//читаем поток, пока есть что читать
while (sr.Read(buffer, 0, nsize) > 0)
{
//переводим массив символов в строку через кодировку dos866
string sym5 = System.Text.Encoding.GetEncoding(866).GetString(buffer));
//далее выполняем действия с полученным текстом
//.....
}
}
catch (Exception error)
{
MessageBox.Show("Ошибка при запуске!\n" + error.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// просто заглушка
/// </summary>
/// <param name="ar"></param>
void Res(IAsyncResult ar)
{
}
//завершение запущенного процесса
private void whenExitProcess(Object sender, EventArgs e)
{
//данные об окончании работы программы
}
Вот что у нас получилось. Как видите читать можно хоть по 20 символов, задавая размер буфера. Задавайте вопросы, будем разбирать что не понятно.
Так же можно купить люстру в Киеве
Популярность: 5%
Еще по этой теме:
- Читаем стандартный вывод консольного приложения + DOS to UTF
- Альтернативные потоки данных NTFS с примером использования на C#
Если у вас возникли вопросы, вы можете оставить их в комментариях

