получить содержимое консольного окна

Тема в разделе "WASM.WIN32", создана пользователем slow, 20 янв 2006.

  1. slow

    slow New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2004
    Сообщения:
    615
    как получить содержимое консольного окна в виде текста если известен его handle?

    А решение этой задачи точно есть :dntknw:( Ведь винда это как-то делает (Правка -> Выделить -> Копировать... и т.п.)

    Заранее сэнкс
     
  2. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    slow







    А с чего ты взял что эта функциональность должна быть доступна в юзере?
     
  3. alpet

    alpet Александр

    Публикаций:
    0
    Регистрация:
    21 сен 2004
    Сообщения:
    1.221
    Адрес:
    Russia
    Функции в помощь:

    AttachConsole

    ReadConsole

    ReadConsoleOutput

    GetConsoleSelectionInfo

    Многие функции есть только в NT-системах. В других лучше использовать свое консольное приложение как редиректор, запускающий чужое (см. CreateProcess).



    По этой ссылке, можно загрузить пример редиректора консоли, на Дельфийском наречии.
     
  4. OLS

    OLS New Member

    Публикаций:
    0
    Регистрация:
    8 янв 2005
    Сообщения:
    322
    Адрес:
    Russia
    The ReadConsoleOutput function reads character and color attribute data from a rectangular block of character cells in a console screen buffer, and the function writes the data to a rectangular block at a specified location in the destination buffer.



    BOOL ReadConsoleOutput(



    HANDLE hConsoleOutput, // handle of a console screen buffer

    PCHAR_INFO lpBuffer, // address of buffer that receives data

    COORD dwBufferSize, // column-row size of destination buffer

    COORD dwBufferCoord, // upper-left cell to write to

    PSMALL_RECT lpReadRegion // address of rectangle to read from

    );
     
  5. OLS

    OLS New Member

    Публикаций:
    0
    Регистрация:
    8 янв 2005
    Сообщения:
    322
    Адрес:
    Russia
    о! опередили
     
  6. Guest

    Guest Guest

    Публикаций:
    0
    а ReadFile не покатит?
     
  7. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    alpet

    OLS

    Corleone



    Я так понял товарисча интересует чтение из чужого консольного окна.
     
  8. alpet

    alpet Александр

    Публикаций:
    0
    Регистрация:
    21 сен 2004
    Сообщения:
    1.221
    Адрес:
    Russia
    _DEN_

    И в чем же сложность тогда? Если предполагается подключаться к уже запущенному процессу, не имея на руках описателей консоли, можно просто внедрить DLL.
     
  9. slow

    slow New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2004
    Сообщения:
    615
    спасiбо товарiсчi

    вопрос решioн
     
  10. delpher

    delpher New Member

    Публикаций:
    0
    Регистрация:
    30 июн 2006
    Сообщения:
    5
    Адрес:
    Russia
    Для тех, кто, как и я, долго ...лся в поисках решения проблемы:

    Чтение текста из чужого консольного окна (на Delphi 5). К сожалению, пока только для XP:
    Код (Text):
    1. type
    2.    TAttachConsole = function (dwProcessId: DWORD): LongBOOL stdcall;
    3.  
    4. var
    5.   AttachConsole: TAttachConsole;
    6.   mProcessID, Hcwnd, chRead: Cardinal;
    7.   BufInfo: _CONSOLE_SCREEN_BUFFER_INFO;
    8.   lpCh: PChar;
    9.   Coord: _COORD;
    10.   i: Integer;
    11.  
    12. begin
    13.   @AttachConsole := GetProcAddress(GetModuleHandle('kernel32.dll'), 'AttachConsole');
    14.   GetWindowThreadProcessId(FindWindow(nil, '[1/2] {D:\MyFolder\zDown\Тексты} - Far'), // Текст заголовка должен быть записан сюда полностью
    15.                            @mProcessID);
    16.  
    17.   if AttachConsole(mProcessID) then begin
    18.     Hcwnd:=GetStdHandle(STD_OUTPUT_HANDLE);
    19.     GetConsoleScreenBufferInfo (Hcwnd, BufInfo);
    20.     GetMem(lpCh, BufInfo.dwMaximumWindowSize.Y*BufInfo.dwMaximumWindowSize.X);
    21.     try
    22.       for i:=0 to BufInfo.dwMaximumWindowSize.Y-1 do begin
    23.          Coord.X := 0;
    24.          Coord.Y := i;
    25.          ReadConsoleOutputCharacter(Hcwnd, lpCh, BufInfo.dwMaximumWindowSize.X, Coord, chRead);
    26.          StrFile(lpCh, ChangeFileExt(ParamStr(0), '.log'), False);
    27.       end;
    28.     finally
    29.       FreeMem(lpCh, BufInfo.dwMaximumWindowSize.Y*BufInfo.dwMaximumWindowSize.X);
    30.     end;
    31.   end;
    32. end.
    архив с исходником приложен.

    [​IMG] 1972767194__ConsoleScreenBuffer.rar
     
  11. delpher

    delpher New Member

    Публикаций:
    0
    Регистрация:
    30 июн 2006
    Сообщения:
    5
    Адрес:
    Russia
    >можно просто внедрить DLL.

    А вот это оказалось не так просто. Что с помощью хука WH_GETMESSAGE, что с помощью CreateRemoteThread, один фиг - в консольное окно, может, и внедряется, но вот проверить это никак - не могу оттуда даже имя модуля посмотреть - в случае WH_GETMESSAGE не вызывается функция обработки сообщений (проверял на гуишном окне - на нем вызывается нормально), а в случае CreateRemoteThread полная тишина и отсутствие любых ошибок и исключений.

    Подскажите в таком случае, как внедрить dll в процесс с консольным окном, чтобы потом можно было получить у него STD_OUTPUT_HANDLE?
     
  12. delpher

    delpher New Member

    Публикаций:
    0
    Регистрация:
    30 июн 2006
    Сообщения:
    5
    Адрес:
    Russia
    поправка:

    в случае CreateRemoteThread, DLLEntryPoint при инжекте не вызывается, а если смотреть имя модуля в другой процедуре, вызываемой из внедряющей проги, получим имя модуля этой самой проги, а не того модуля, в чей процесс внедряли.



    Возможно ли в принципе внедрить dll в процесс консольного окна и как?
     
  13. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Консольное - не GUI, там нет цикла сообщений и прочих GUI-премудростей. Следовательно, и хуки не работают.
     
  14. alpet

    alpet Александр

    Публикаций:
    0
    Регистрация:
    21 сен 2004
    Сообщения:
    1.221
    Адрес:
    Russia
    delpher

    Можно внедрится посредством Toolhelp32 и потоковых (SetThreadContext) функций, в любой процесс - главное чтобы хватало привелегий.
     
  15. delpher

    delpher New Member

    Публикаций:
    0
    Регистрация:
    30 июн 2006
    Сообщения:
    5
    Адрес:
    Russia
    Привилегий хватит - на своей машине я админ...
     
  16. S_Alex

    S_Alex Alex

    Публикаций:
    0
    Регистрация:
    27 авг 2004
    Сообщения:
    561
    Адрес:
    Ukraine
    Доброго времени суток!
    эта тема для меня стала актуальна.

    Хочу прикрутить WinAVR к RadASM 3.0. Но утилитка Make, будь она не ладна, не хочет работать на прямую.
    Переназначение стандартного вывода (cmd /K "make -B -C default" > 1.txt) тоже не дает требуемого результата.

    Может кто-то уже сделал что-то похожее?

    Ато я тут нагородил.

    Код (Text):
    1. GetConsoleTxt proc lpTitle:DWORD
    2. LOCAL  mProcessID :DWORD
    3. LOCAL  Hcwnd      :DWORD
    4. LOCAL  chRead     :DWORD
    5. LOCAL  BufInfo    :CONSOLE_SCREEN_BUFFER_INFO;
    6. LOCAL  lpCh       :DWORD
    7. LOCAL  Coord      :COORD;
    8. LOCAL  hWndC      :DWORD;
    9.  
    10.  
    11.   mov [hWndC],  rv(FindWindow, NULL,[lpTitle])
    12.  
    13.  
    14.   invoke GetWindowThreadProcessId,[hWndC],ADDR[mProcessID];
    15.  
    16.   .if rv(AttachConsole,[mProcessID])
    17.     mov [Hcwnd],rv(GetStdHandle,STD_OUTPUT_HANDLE);
    18.     fn GetConsoleScreenBufferInfo,[Hcwnd],ADDR[BufInfo];
    19.     PrintHex BufInfo.dwMaximumWindowSize.x
    20.     movzx edx,  [BufInfo.dwMaximumWindowSize.x]
    21.     PrintDec edx
    22.    
    23.     PrintHex BufInfo.dwMaximumWindowSize.y
    24.    
    25.     movzx ecx,  [BufInfo.dwMaximumWindowSize.y]
    26.     movzx edx,  [BufInfo.dwMaximumWindowSize.y]
    27.     mov [lpCh], rv(LocalAlloc,LMEM_FIXED,rv(MulDiv,ecx,edx,1))
    28.    
    29.     movzx edx,  [BufInfo.dwMaximumWindowSize.x]
    30.     mov BYTE ptr[eax+edx],0
    31.    
    32.     xor eax,eax
    33.     .while ax<[BufInfo.dwMaximumWindowSize.y]
    34.       mov [Coord.x],0
    35.       mov [Coord.y],ax
    36.       push  eax
    37.       movzx edx,  [BufInfo.dwMaximumWindowSize.x]
    38.       fn ReadConsoleOutputCharacter,[Hcwnd],[lpCh], edx, DWORD ptr[Coord],ADDR[chRead];
    39.       PrintStringByAddr lpCh
    40.       movzx edx,  [BufInfo.dwMaximumWindowSize.x]
    41.       mov BYTE ptr[eax+edx],0
    42.  
    43.       invoke OutputString,[lpCh]
    44.       invoke OutputString,addr szCR
    45.       pop   eax
    46.       inc   eax
    47.       PrintDec eax
    48.     .endw
    49.     invoke FreeConsole
    50.     invoke LocalFree,[lpCh]
    51.   .endif;
    52.  
    53.   ret
    54.  
    55. GetConsoleTxt endp
    Всё хорошо. Инфу с окна снимаю. Но есть пару НО.

    1. invoke FreeConsole - если эта строчка есть приложение вылетает. Приложение вкурсе что произошла ошибка и предлагает сохраниться.
    2. invoke FreeConsole - если этой строчки нет, то всё ОК пока не закроешь новую консоль приложение опять вылетает безо всякого сообщения.