Во время «развертывания» решения из этого вопроса на нескольких машинах я заметил, что некоторые одноядерные машины дают ужасные результаты (например, решение неэффективно работает на атоме intel).
То, что здесь происходит, следующее.Я звоню SetWinEventHook(...)
, чтобы получить обратные вызовы для изменений консоли.Из-за уведомления вне контекста синхронизация между обработкой событий и дальнейшими изменениями в консоли отсутствует, поэтому, хотя многоядерные машины работают хорошо (не идеально, кстати), одноядерные машины создают из этого беспорядок.
Итак, я продолжил включать уведомление In-Context, поскольку оно должно быть синхронным в соответствии с msdn.В c # это похоже на запрос диска Infinite Improbability Drive, поэтому я создал простую dll в C, которая может выполнять грязную работу, и общаться с dll из c #.Пока все хорошо.
Как оказалось, обратные вызовы происходят в conhost.exe, а не в процессе, владеющем консолью.Теперь это представляет проблему, так как в обратном вызове я не могу найти способ получить доступ к буферу вывода консоли в контексте conhost.exe.Или, точнее, я не могу найти способ справиться с этим.Вот что доступно: Дескриптор к окну консоли, идентификаторы процесса как консольного приложения, так и conhost.exe и канал к консольному приложению.
А вот что я попробовал:
- с использованием
GetStdHandle(...)
, приводит к неверным дескрипторам (имеет смысл в контексте conhost.exe) - с использованием
CreateFile("CONOUT$"...)
, dito - Использование канала для чтения консольного приложения из буфера вывода приводит к взаимоблокировке.Я подозреваю, что механизм блокировки для предотвращения чтения во время записи имеет смысл.
- , дублирующий дескриптор буфера вывода и пропускающий его через канал.Не радует, потому что дескрипторы консоли не могут быть дублированы на внешний процесс.
- присоединяет процесс conhost.exe к консоли обслуживаемого им процесса консоли, а затем выполняет функцию CreateFile.Хорошо, это был мой любимый, но он также не работает, так как
AttachConsole(...)
блоков, аналогично 3.
У кого-то есть идеи, что попробовать дальше?Мои навыки c / c ++ / winapi в лучшем случае являются промежуточными, поэтому вполне возможно, что я что-то упустил.Хорошо, очевидным было бы выбросить все это за борт и просто опросить выходной буфер на предмет изменений, но я бы посчитал это последним вариантом.Я предполагаю, что MS был достаточно умен, чтобы быть уверенным, что события In Context или Out of Context действительно могли быть использованы, и поэтому я должен что-то упустить.