Дано консольное приложение. В него вводится какая-то строка, положим:
String s = "Test string"
Console.WriteLine(s);
Как теперь прочитать буфер консоли? С помощью класса Console или ещё чего-то? В Console я не смог найти/постичь существование таких инструментов. Есть вообще какая то возможность получить прямой доступ к буферу консольного приложения? Метод Console.Clear вот, например, есть, значит где-то всё-таки текст хранится...
Здравствуйте, lesovick, Вы писали:
L>Дано консольное приложение. В него вводится какая-то строка, положим: L>
L>String s = "Test string"
L>Console.WriteLine(s);
L>
L>Как теперь прочитать буфер консоли?
зачем? в приведённом примере содержимое консоли можно получить из переменной s.
L>С помощью класса Console или ещё чего-то? В Console я не смог найти/постичь существование таких инструментов. Есть вообще какая то возможность получить прямой доступ к буферу консольного приложения? Метод Console.Clear вот, например, есть, значит где-то всё-таки текст хранится...
если запускать чужой экзешник, то можно перенаправить стандартный вывод. на этом идеи заканчиваются, поскольку и затея не вполне ясна...
Здравствуйте, lesovick, Вы писали:
L>Как теперь прочитать буфер консоли? С помощью класса Console или ещё чего-то? В Console я не смог найти/постичь существование таких инструментов. Есть вообще какая то возможность получить прямой доступ к буферу консольного приложения? Метод Console.Clear вот, например, есть, значит где-то всё-таки текст хранится...
В Win API это делается с помощью ReadConsoleOutput
Здравствуйте, Neco, Вы писали:
N>Здравствуйте, lesovick, Вы писали:
L>>Дано консольное приложение. В него вводится какая-то строка, положим: L>>
L>>String s = "Test string"
L>>Console.WriteLine(s);
L>>
L>>Как теперь прочитать буфер консоли? N>зачем? в приведённом примере содержимое консоли можно получить из переменной s.
Архитектура такая, что WriteLine происходит в сторонней библиотеке. Гадать что она выдаст в консоль — не вариант. Хочется тупо скопировать буфер. Если к нему ведут хоть какие-то ниточки.
L>>С помощью класса Console или ещё чего-то? В Console я не смог найти/постичь существование таких инструментов. Есть вообще какая то возможность получить прямой доступ к буферу консольного приложения? Метод Console.Clear вот, например, есть, значит где-то всё-таки текст хранится... N>если запускать чужой экзешник, то можно перенаправить стандартный вывод. на этом идеи заканчиваются, поскольку и затея не вполне ясна...
Примеры того, что можно из чужого экзешника организовать приём я уже видел. Мне надо из своего.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, lesovick, Вы писали:
L>>Как теперь прочитать буфер консоли? С помощью класса Console или ещё чего-то? В Console я не смог найти/постичь существование таких инструментов. Есть вообще какая то возможность получить прямой доступ к буферу консольного приложения? Метод Console.Clear вот, например, есть, значит где-то всё-таки текст хранится...
PD>В Win API это делается с помощью ReadConsoleOutput
PD>http://msdn.microsoft.com/en-us/library/windows/desktop/ms684965%28v=vs.85%29.aspx
PD>Аналоги в .net мне неизвестны. Ниже пример вызова этой функции через pInvoke
PD>http://stackoverflow.com/questions/12355378/read-from-location-on-console-c-sharp
Здравствуйте, lesovick, Вы писали:
L>Дано консольное приложение. В него вводится какая-то строка, положим:
L>
L>String s = "Test string"
L>Console.WriteLine(s);
L>
L>Как теперь прочитать буфер консоли? С помощью класса Console или ещё чего-то? В Console я не смог найти/постичь существование таких инструментов. Есть вообще какая то возможность получить прямой доступ к буферу консольного приложения? Метод Console.Clear вот, например, есть, значит где-то всё-таки текст хранится...
Это переназначение стандпртного вывода в некий иной поток. Можно , конечно, переназначить, но тогда в консоли ничего не будет, а будет в этом потоке. Это ИМХО не то, что ТС нужно — он хочет прочитать то, что записано в консоль.
Здравствуйте, Pavel Dvorkin, Вы писали:
R>>Console.SetOut
PD>Это переназначение стандпртного вывода в некий иной поток. Можно , конечно, переназначить, но тогда в консоли ничего не будет, а будет в этом потоке. Это ИМХО не то, что ТС нужно — он хочет прочитать то, что записано в консоль.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, rameel, Вы писали:
R>>Старый поток можно не удалять, а завернуть в свой
PD>То есть обернуть консольный поток в StreamWriter ? Можно, наверное, но тогда как потом прочитать, то , что туда попало ?
Я извиняюсь: где вы увидели в Console поток? Там есть только TextWriter, ни одного поточного члена. Stream и TextWriter не связаны иерархией наследования, и в StreamWriter TextWriter не завернёшь.
Да, хорошо, если бы в Console были потоки. Вариант с подменой Console.Out на свой читабельный поток не подходит. Какие-нибудь извращения типа параллельной записи и туда и туда, переключаясь с помощью SetOut не катят. Надо именно увидеть, что WriteLine в консоль независимо от меня навалила.
Здравствуйте, lesovick, Вы писали:
L>Архитектура такая, что WriteLine происходит в сторонней библиотеке. Гадать что она выдаст в консоль — не вариант. Хочется тупо скопировать буфер. Если к нему ведут хоть какие-то ниточки.
мне почему-то кажется, что после записи содержимое консоли находится во власти операционки. по сути то, что мы видим в консоли уже не принадлежит текущему процессу (ведь процесс может уже завершить свою работу, а содержимое консоли останется).
меня не покидает подозрение, что проще это сделать на уровне дотнета.
если уж речь зашла об извращениях, то например вот тут: http://www.codeproject.com/Articles/37549/CLR-Injection-Runtime-Method-Replacer
Здравствуйте, lesovick, Вы писали:
L>Я извиняюсь: где вы увидели в Console поток? Там есть только TextWriter, ни одного поточного члена. Stream и TextWriter не связаны иерархией наследования, и в StreamWriter TextWriter не завернёшь.
С точки зрения натива (WinAPI) вывод в консоль — это вывод в файл с именем CONOUT$. В WinAPI нет понятия потока, это понятие из вышележащей надстройки (C++ RTL, .NET). Поэтому я и подумал об оборачивании потока. Может быть, здесь это и не реализовано.
L>Да, хорошо, если бы в Console были потоки. Вариант с подменой Console.Out на свой читабельный поток не подходит. Какие-нибудь извращения типа параллельной записи и туда и туда, переключаясь с помощью SetOut не катят. Надо именно увидеть, что WriteLine в консоль независимо от меня навалила.
Здравствуйте, rameel, Вы писали:
L>>Как теперь прочитать буфер консоли? С помощью класса Console или ещё чего-то? В Console я не смог найти/постичь существование таких инструментов. Есть вообще какая то возможность получить прямой доступ к буферу консольного приложения? Метод Console.Clear вот, например, есть, значит где-то всё-таки текст хранится...
R>Console.SetOut R>http://msdn.microsoft.com/en-us/library/system.console.setout%28v=vs.110%29.aspx
Идея про Console.SetOut, конечно, хорошая, но вот срабатывает не всегда.
Если вывод в консоль идет буферизированный, то SetOut получит данные при переполнении буфера (а это, если я правильно ошибаюсь, 4Кб), ну или при завершении приложения.
Перехватить построчно в таких случаях не получится, разве что через RTConsole (или аналог), но там есть свои грабли...
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, lesovick, Вы писали:
L>>Как теперь прочитать буфер консоли? С помощью класса Console или ещё чего-то? В Console я не смог найти/постичь существование таких инструментов. Есть вообще какая то возможность получить прямой доступ к буферу консольного приложения? Метод Console.Clear вот, например, есть, значит где-то всё-таки текст хранится...
PD>В Win API это делается с помощью ReadConsoleOutput
PD>http://msdn.microsoft.com/en-us/library/windows/desktop/ms684965%28v=vs.85%29.aspx
PD>Аналоги в .net мне неизвестны. Ниже пример вызова этой функции через pInvoke
PD>http://stackoverflow.com/questions/12355378/read-from-location-on-console-c-sharp
Проверил — всё работает. Отличный пример для решения поставленной задачи. Спасибо большое!
Здравствуйте, AndrewVK, Вы писали:
AVK>Разницы никакой нет.
Разницы нет, если , как предложил Neco, перенаправить консольный вывод. Но в этом случае в самой консоли (в буфере консоли) данные будут отсутствовать, и к чему это приведет в случае примера ТС — бог знает. Если тот, кто в консоль выводит, еще потом оттуда и читает, то он будет крайне недоволен, не обнаружив там то, что он туда записал, как он считает.
Если же речь идет о том, чтобы данным позволить оказаться в консольном окне (буфере, точнее), то разница есть. Она просто заключается в том, что прием, который я предложил, работает для окна консоли своего процесса, а для консоли чужого процесса не может быть прямо применен вообще. Добраться к буферу консоли чужого процесса можно, наверное, разве что через хуки.
Сложная это штука — консоли. Spy++ не позволяет исследовать поток сообщений консольного окна. Нельзя создать более одного консольного окна на процесс. Наконец, консольное окно может наследоваться от процесса — родителя, после чего оно как-то принадлежит и родителю, и потомку...
Remarks
A process can be attached to at most one console. If the calling process is already attached to a console, the error code returned is ERROR_ACCESS_DENIED (5).
Естественно, я о ней не забыл. Но для этого придется отказаться от своей консоли.
А вообще, да, это все в продолжение того, о чем я говорил. Можно унаследовать консоль, можно присоединиться к чужой, отказавшись от своей (родной или унаследованной). Одного нельзя — иметь 2 консоли, то есть имея консоль, добраться к чужой консоли в пределах данного процесса. Только через хук, который сработает в чужом процессе.
Здравствуйте, AndrewVK, Вы писали:
PD>>Естественно, я о ней не забыл. Но для этого придется отказаться от своей консоли.
AVK>А с чего ты взял что своя консоль у мониторящего процесса вообще есть?
Может и не быть, а может быть, и во втором случае решение будет ущербным.