![]() |
|
|
Регистрация Восстановить пароль |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
![]() |
|
Опции темы | Поиск в этой теме |
![]() |
#1 |
Пользователь
Регистрация: 19.09.2007
Сообщений: 19
|
![]()
Добрый день. Вопрос пока в общих чертах. У консольной программы есть один основной поток вывода который построчно выводит информацию в консоль. Обычно при перенаправление вывода в файл, всё хорошо перенаправляется.
Но тут столкнулся с тем что FMLECmd.exe выводит информацию в виде таблице и она динамически меняется (СМ снимок, динамическая часть окна выделена). Вот вопрос, как мне перехватить даный динамический вывод? Перенаправление потока не помогает, он не отабражает данную динамическую область. как мне перехватить данный вывод? |
![]() |
![]() |
![]() |
#2 |
Регистрация: 06.09.2012
Сообщений: 3
|
![]()
Hello !
И как - удалось разрешить эту проблему ? У меня - аналогичнаяя ситуация .... |
![]() |
![]() |
![]() |
#3 |
Пользователь
Регистрация: 19.09.2007
Сообщений: 19
|
![]()
Да решил.
Вот тебе мой код. Если что пеши в Skype. viktor-_-skype if AttachConsole(PID) then begin conHandle := GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleScreenBufferInfo(conHandl e, BufInfo); GetMem(p, BufInfo.dwMaximumWindowSize.X+1); try for i := 0 to BufInfo.dwSize.Y - 1 do begin Crd.X := 0; Crd.Y := i; ReadConsoleOutputCharacter(conHandl e, p, BufInfo.dwMaximumWindowSize.X, Crd, read); s:= Trim(Copy(StrPas(p), 1,80)); if s <> '' then Mas[Masi]:=s; end; finally FreeMem(p, BufInfo.dwMaximumWindowSize.X+1); end; FreeConsole; end; |
![]() |
![]() |
![]() |
#4 |
Регистрация: 06.09.2012
Сообщений: 3
|
![]()
Спасибо !
У меня C# ... И я скомпоновал ещё с чем - то ... вот что вышло : if (!AttachConsole(cur_fmle.Id)) { MessageBox.Show("Ошибка - консоль не присоединена ... "); return; } hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO info = new CONSOLE_SCREEN_BUFFER_INFO(); GetConsoleScreenBufferInfo(hStdOut, ref info); //set up the dimensions of my buffer (3 by 3) COORD myBufferSize; myBufferSize.X = info.dwSize.X;//(short)(info.srWindow.Left - info.srWindow.Right + 1); myBufferSize.Y = info.dwSize.Y;// (short)(info.srWindow.Bottom - info.srWindow.Top + 1); // we're going to read a 3x3 square buffer from the console. // so the buffer array needs to be 3 x 3 = 9 structs in size CHAR_INFO[] myCharInfo = new CHAR_INFO[Math.Abs(myBufferSize.X) * Math.Abs(myBufferSize.Y)]; //set up where within the buffer to PUT what we read //(my buffer is only 3x3 and I'm reading a 3x3 square // so I better start writing to the buffer at 0,0 or // I'm going to overflow the buffer) COORD myBufferPosition; myBufferPosition.X = 0; myBufferPosition.Y = 0; //set up what part of the screen buffer to read. //(any Left, Right, Top, Bottom could be used. I just thought // this made an interesting example.) SMALL_RECT mySmallRect; mySmallRect.Bottom = info.dwSize.Y; mySmallRect.Left = 0; mySmallRect.Right = info.dwSize.X; mySmallRect.Top = 0; //do the actual read of the screen buffer using // kernel32.dll's ReadConsoleOutput function ReadConsoleOutput(hStdOut, myCharInfo, myBufferSize, myBufferPosition, ref mySmallRect); StringBuilder sb = new StringBuilder(); sb.Append(myCharInfo.Select(p => p.UnicodeChar).ToArray()); FreeConsole(); MessageBox.Show("DONE !!!"); =================================== ==================== Теперь чуть дальше. Это все заработало если я вручную запускаю : FMLECmd.exe /p C:\config.xml Но если я запускаю из программы - как внешний процесс - не работает : proc = new System.Diagnostics.Process(); proc.StartInfo.FileName = @"C:\Program Files\Adobe\Flash Media Live Encoder 3.2\FMLECmd.exe"; proc.StartInfo.Arguments = @"/p C:\config.xml"; /*********/ proc.StartInfo.UseShellExecute = false; proc.StartInfo.CreateNoWindow = true; proc.StartInfo.RedirectStandardOutp ut = true; proc.StartInfo.RedirectStandardErro r = true; /**********/ proc.EnableRaisingEvents = true; // при закрытии процесса будет вызвано событие Exited proc.Exited += new EventHandler(proc_Exited); // добавляем обработчик события proc.Start(); // запускаем программу =================================== ========== Вышеуказанные комбинации Redirect'ov и прочих UseShellExecute - не помогают .... Нет каких-то идей ?! Большое спасибо ! |
![]() |
![]() |
![]() |
#5 |
Регистрация: 06.09.2012
Сообщений: 3
|
![]()
... Всё - кажись окончательно победил ! Вот код на C#
public class ContentConsole { [DllImport("kernel32.dll")] static extern bool AttachConsole(int processID); [DllImport("kernel32.dll")] static extern bool FreeConsole(); [DllImport("kernel32.dll")] static extern IntPtr GetStdHandle(int nStdHandle); [DllImport("kernel32.dll")] private static extern bool ReadConsoleOutputCharacter(IntPtr hConsoleOutput, [Out] char[] lpCharacter, uint nLength, COORD dwReadCoord, out uint lpNumberOfCharsRead); //COORD struct [StructLayout(LayoutKind.Sequential)] private struct COORD { public short X; public short Y; public COORD(short X, short Y) { this.X = X; this.Y = Y; } } private static IntPtr hStdOut; private static string file_log = Path.Combine(Path.GetDirectoryName( ControlMultiCodeClass.file_log), "FMLECmdConsole.log"); public static void GetContentConsole(int PID, string coder_name) { if (!AttachConsole(PID)) { LogClass.WriteLog("Ошибка - консоль не присоединена ...", file_log); // FreeConsole(); return; } const int STD_OUTPUT_HANDLE = -11; hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); string text = ""; // new StringBuilder(); bool need_append = false; for (int i = 0; i < Console.BufferHeight; i++) { string cur_line = GetLine(i); // text.AppendLine(GetLine(i)); if (cur_line.ToLower().Contains("stati stics")) need_append = true; if (need_append) text += cur_line + Environment.NewLine; if (cur_line.ToLower().Contains("strea ming")) break; } if (text != "") { LogClass.WriteLog(coder_name + " Статистика FMLECmd. PID = " + PID + Environment.NewLine + text + Environment.NewLine, file_log); } FreeConsole(); } private static string GetLine(int line) { char[] buffer = new char[Console.BufferWidth]; string result_text = ""; uint garbage; // if (!ReadConsoleOutputCharacter(hStdOu t, buffer, (uint)buffer.Length, new COORD(0, (short)line), out garbage)) // throw new InvalidOperationException("Could not read console output."); try { ReadConsoleOutputCharacter(hStdOut, buffer, (uint)buffer.Length, new COORD(0, (short)line), out garbage); result_text = new string(buffer); } catch (Exception ex) { result_text = ex.Message; } return result_text; } } ////////////// А вот как вызывать : ContentConsole.GetContentConsole(cu r_encoder.proc.Id, cur_encoder.coder_name); ////////////// Один из прототипов всего этого дела - здесь : http://www.gamedev.net/blog/1202/ent...t-in-c-part-2/ тут - построчное чтение консоли ////////////// вот ещё : http://www.gotdotnet.ru/forums/2/137794/ тут - блочно. И не всегда работает. Почему - не успел разобраться Работает если FMLECmd запускаю как отдельную прогу - в командной строке или в диско-командере каком А вот если запускать как процесс : proc.StartInfo.FileName = "C:\\FMLEcmd.exe"; proc.StartInfo.Arguments = @"/p " + "c:\\config.xml"; то почему-то не читает консоль .... PS. Всем спасибо за помощь и идеи ! |
![]() |
![]() |
![]() |
#6 |
Пользователь
Регистрация: 19.09.2007
Сообщений: 19
|
![]()
dpd
Странно, у меня в Delphi 7 всё хорошо работало. Даже с FAR2 всё считывает )))) |
![]() |
![]() |
![]() |
![]() |
||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Вывод *.bmp в консоль | stas135642 | Общие вопросы C/C++ | 4 | 30.10.2011 02:00 |
Вывод в консоль в линуксе | arcer | Общие вопросы C/C++ | 2 | 18.11.2010 20:47 |
winpcap вывод ip в консоль | draculito | C/C++ Сетевое программирование | 3 | 14.11.2010 21:38 |
параллельный вывод в консоль линукс | arcer | Общие вопросы C/C++ | 6 | 09.11.2010 22:20 |
Вывод времени в консоль. | BlincAttack | Общие вопросы .NET | 2 | 06.10.2009 14:57 |