Перехват вывода консольного окна, запущенного другой программой - VB

Узнай цену своей работы

Формулировка задачи:

Привет всем барсикам и заглянувшим в тему ! Есть программа, которая создает консольное окно, выполняет в нем команды и сразу закрывает это окно. Как прочитать весь текст из такого окна. Допустим, я отслежу таймером изменение хендла по GetForegroundWindow, найдя окно консоли. А как дальше? Чем считать текст? Структура STARTUPINFO еще имеет влияние на поведение процесса, если внести в нее модификации уже после запуска процесса?

Решение задачи: «Перехват вывода консольного окна, запущенного другой программой»

textual
Листинг программы
  1. Option Explicit
  2.  
  3. Private Type SMALL_RECT
  4.     Left As Integer
  5.     Top As Integer
  6.     Right As Integer
  7.     Bottom As Integer
  8. End Type
  9. Private Type CONSOLE_SCREEN_BUFFER_INFO
  10.     dwSize As Long
  11.     dwCursorPosition As Long
  12.     wAttributes As Integer
  13.     srWindow As SMALL_RECT
  14.     dwMaximumWindowSize As Long
  15. End Type
  16.  
  17. Private Declare Function GetConsoleScreenBufferInfo Lib "kernel32" (ByVal hConsoleOutput As Long, lpConsoleScreenBufferInfo As CONSOLE_SCREEN_BUFFER_INFO) As Long
  18. Private Declare Function RegisterShellHookWindow Lib "user32" (ByVal hwnd As Long) As Long
  19. Private Declare Function DeregisterShellHookWindow Lib "user32" (ByVal hwnd As Long) As Long
  20. Private Declare Function RegisterWindowMessage Lib "user32" Alias "RegisterWindowMessageW" (ByVal lpString As Long) As Long
  21. Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongW" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
  22. Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongW" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
  23. Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  24. Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
  25. Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExW" (lpVersionInformation As Any) As Long
  26. Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
  27. Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
  28. Private Declare Function QueryFullProcessImageName Lib "kernel32" Alias "QueryFullProcessImageNameW" (ByVal hProcess As Long, ByVal dwFlags As Long, ByVal lpExeName As Long, lpdwSize As Long) As Long
  29. Private Declare Function AttachConsole Lib "kernel32" (ByVal ProcessID As Long) As Boolean
  30. Private Declare Function FreeConsole Lib "kernel32" () As Long
  31. Private Declare Function GetStdHandle Lib "kernel32" (ByVal nStdHandle As Long) As Long
  32. Private Declare Function ReadConsoleOutputCharacter Lib "kernel32" Alias "ReadConsoleOutputCharacterW" (ByVal hConsoleOutput As Long, ByVal lpCharacter As Long, ByVal nLength As Long, ByVal dwReadCoord As Long, lpNumberOfCharsRead As Long) As Long
  33. Private Declare Function ReadConsole Lib "kernel32" Alias "ReadConsoleA" (ByVal hConsoleInput As Long, lpBuffer As Any, ByVal nNumberOfCharsToRead As Long, lpNumberOfCharsRead As Long, lpReserved As Any) As Long
  34.  
  35. Private Const GWL_WNDPROC                       As Long = (-4)
  36. Private Const GWL_USERDATA                      As Long = (-21)
  37. Private Const HSHELL_WINDOWCREATED              As Long = &H1
  38. Private Const PROCESS_QUERY_LIMITED_INFORMATION As Long = &H1000
  39. Private Const PROCESS_QUERY_INFORMATION         As Long = &H400
  40. Private Const INVALID_HANDLE_VALUE              As Long = -1
  41. Private Const MAX_PATH                          As Long = 260
  42. Private Const STD_OUTPUT_HANDLE                 As Long = -11&
  43.  
  44. Dim ShellMsg        As Long
  45. Dim verInit         As Boolean
  46. Dim IsVistaAndLater As Boolean
  47. Dim ConsolePath     As String
  48. Dim hOut            As Long
  49. Dim isAttached      As Boolean
  50.  
  51. ' Path - ГЇГіГІГј äî ГЄГ®Г*ñîëè
  52. Public Sub Hook(ByVal hwnd As Long, Path As String)
  53.     Dim prev As Long, inf(68) As Long
  54.     ConsolePath = Path
  55.     inf(0) = 276: GetVersionEx inf(0): IsVistaAndLater = inf(1) >= 6
  56.     RegisterShellHookWindow hwnd
  57.     ShellMsg = RegisterWindowMessage(StrPtr("SHELLHOOK"))
  58.     prev = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf WndProc)
  59.     SetWindowLong hwnd, GWL_USERDATA, prev
  60. End Sub
  61. Public Sub Unhook(ByVal hwnd As Long)
  62.     Dim prev As Long
  63.     prev = GetWindowLong(hwnd, GWL_USERDATA)
  64.     If prev = 0 Then Exit Sub
  65.     SetWindowLong hwnd, GWL_WNDPROC, prev
  66.     SetWindowLong hwnd, GWL_USERDATA, 0
  67. End Sub
  68. ' Ïîëó÷èòü ГІГҐГЄГ±ГІ ГЄГ®Г*ñîëè
  69. Public Function GetConsoleText() As String
  70.     Dim infBuf  As CONSOLE_SCREEN_BUFFER_INFO
  71.     Dim count   As Long
  72.     Dim buf     As String
  73.     Dim i       As Long
  74.     If Not isAttached Then Exit Function
  75.     GetConsoleScreenBufferInfo hOut, infBuf
  76.     count = infBuf.dwSize And &HFFFF&
  77.     buf = Space(count)
  78.     For i = 0 To (infBuf.dwSize \ &H10000) And &HFFFF&
  79.         ReadConsoleOutputCharacter hOut, StrPtr(buf), count, i * &H10000, count
  80.         GetConsoleText = GetConsoleText & buf & vbNewLine
  81.     Next
  82. End Function
  83. ' Îñâîáîäèòü ГЄГ®Г*ñîëü
  84. Public Sub ReleaseConsole()
  85.     FreeConsole
  86.     isAttached = False
  87. End Sub
  88. Private Function WndProc(ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  89.     Dim prev As Long
  90.     Select Case msg
  91.     Case ShellMsg
  92.         If wParam = HSHELL_WINDOWCREATED Then
  93.             ' ÑîçäГ*ëîñü îêГ*Г®
  94.            Dim pid     As Long
  95.             Dim hProc   As Long
  96.             ' Ïîëó÷Г*ГҐГ¬ pid
  97.            GetWindowThreadProcessId lParam, pid
  98.             hProc = OpenProcess(IIf(IsVistaAndLater, PROCESS_QUERY_LIMITED_INFORMATION, PROCESS_QUERY_INFORMATION), False, pid)
  99.             If hProc <> INVALID_HANDLE_VALUE Then
  100.                 Dim Path As String
  101.                 Dim lStr As Long
  102.                 ' Ïîëó÷Г*ГҐГ¬ èìÿ ïðîöåññГ*
  103.                lStr = MAX_PATH
  104.                 Path = Space(lStr)
  105.                 If QueryFullProcessImageName(hProc, 0, StrPtr(Path), lStr) Then
  106.                     If StrComp(ConsolePath, Left$(Path, lStr), vbTextCompare) = 0 Then
  107.                         ' ГЌГ*øëè Г*Г*ГёГҐ îêГ*Г®
  108.                        AttachConsole pid
  109.                         hOut = GetStdHandle(STD_OUTPUT_HANDLE)
  110.                         Unhook hwnd
  111.                         isAttached = True
  112.                     End If
  113.                 End If
  114.                 CloseHandle hProc
  115.             End If
  116.         End If
  117.     Case Else
  118.         prev = GetWindowLong(hwnd, GWL_USERDATA)
  119.         WndProc = CallWindowProc(prev, hwnd, msg, wParam, lParam)
  120.     End Select
  121. End Function

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

15   голосов , оценка 3.8 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы