Получаем текст из консоли

altИногда возникает необходимость получить какие-то данные из консольного окна. Да-да, действительно, бывают такие случаи

Для этих целей я нашел весьма оригинальный способ, старое доброе WinAPI.
Итак начнем…
В WinAPI есть замечательная функция ReadConsoleOutputCharacterA. Заголовок из MSDN (C++):

Только кодкопировать в буфер обменапечать
BOOL WINAPI ReadConsoleOutputCharacterA
__in HANDLE hConsoleOutput,
__out LPTSTR lpCharacter,
__in DWORD nLength,
__in COORD dwReadCoord,
__out LPDWORD lpNumberOfCharsRead
);
Эта функция копирует заданное число символов из консоли, начиная с заданной позиции. Как-раз почти то, что нам нужно.
Ещё нам понадобится функция AttachConsole, которая присоединяет вызывающий процесс к консоли процесса с заданным идентификатором. Заголовок из MSDN (C++):

Только кодкопировать в буфер обменапечать
BOOL WINAPI AttachConsole(
__in DWORD dwProcessId
);
Вот, собственно, и всё что нужно. Теперь совместим все куски воедино и представим в виде функции:

Только кодкопировать в буфер обменапечать
function GetConsoleOutput(pid: Cardinal): ansistring;
var
wnd,stdOut: THandle;
dwProcessID:DWORD;
lpCharacter:ansistring;
BufInfo:TConsoleScreenBufferInfo;
i:integer;
dwReadCoord:_COORD;
lpNumberOfCharsRead:cardinal;
begin
result:=»;
AttachConsole(pid);
stdOut:=GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(stdOut,BufInfo);
SetLength(lpCharacter,BufInfo.dwMaximumWindowSize.Y*BufInfo.dwMaximumWindowSize.X);
for i:=0 to BufInfo.dwMaximumWindowSize.Y-1 do
begin
dwReadCoord.X:=0;
dwReadCoord.Y:=i; ReadConsoleOutputCharacterA(stdout,PansiChar(lpCharacter),BufInfo.dwMaximumWindowSize.X,dwReadCoord,lpNumberOfCharsRead);
Result:=Result+Copy(lpCharacter,0,lpNumberOfCharsRead)+#13#10;
end;
FreeConsole;
end;
Использование процедуры очень простое, вызываем её с указанием идентификатора процесса-владельца консоли, а как результат функция вернёт ANSI-строку всех данных, содержащихся в консоли.
Easy as pie!
Вот и всё, ничего сложного, как обычно, помогли знания WinAPI. Код проверен в реальных условиях и прекрасно работает (Delphi 2010+Windows 7).


Понравилась статья? Поделиться с друзьями: