26

Re: AHK: Как добыть информацию из окна cmd для последующего парсинга

Подскажите, пожалуйста,

msgbox % StrGet(&Buffer, 1000, "UTF-16")

избавляется от символов  `n, `r
Поэтому непонятно, как ее дальше парсить.
Если же тупо скопировать в клипбоард с CMD, либо экспортировать в файл, то `n, `r остаются.

27 (изменено: Malcev, 2014-02-27 00:20:09)

Re: AHK: Как добыть информацию из окна cmd для последующего парсинга

Нарыл такой код.
Работает, но есть вопрос:
Как захватить  хендл экрана консоли не ожидая 5 секунд (sleep 5000)?
То есть инфа вывелась - пошел захват.

#NoTrayIcon
DetectHiddenWindows, on
loop
{
   Run, %comspec% /k echo list volume | diskpart.exe, , hide, pid
   sleep 5000

   ; AttachConsole accepts a process ID.
   if !DllCall("AttachConsole","uint",pid)
   {
      MsgBox AttachConsole failed - error %A_LastError%.
      ExitApp
   }

   ; If it succeeded, console functions now operate on the target console window.
   ; Use CreateFile to retrieve a handle to the active console screen buffer.
   hConOut := DllCall("CreateFile", "str", "CONOUT$", "uint", 0xC0000000, "uint", 7, "PTR", 0, "uint", 3, "uint", 0, "PTR", 0, "PTR")
   if hConOut = -1 ; INVALID_HANDLE_VALUE
   {
      MsgBox CreateFile failed - error %A_LastError%.
      ExitApp
   }

   ; Allocate memory for a CONSOLE_SCREEN_BUFFER_INFO structure.
   VarSetCapacity(info, 24, 0)

   ; Get info about the active console screen buffer.
   if(!DllCall("GetConsoleScreenBufferInfo", "PTR", hConOut, "PTR", &info))
   {
      MsgBox GetConsoleScreenBufferInfo failed - error %A_LastError%.
      ExitApp
   }

   ; Determine which section of the buffer is on display.
   ConWinLeft := NumGet(info, 10, "Short")     ; info.srWindow.Left
   ConWinTop := NumGet(info, 12, "Short")      ; info.srWindow.Top
   ConWinRight := NumGet(info, 14, "Short")    ; info.srWindow.Right
   ConWinBottom := NumGet(info, 16, "Short")   ; info.srWindow.Bottom
   ConWinWidth := ConWinRight-ConWinLeft+1
   ConWinHeight := ConWinBottom-ConWinTop+1
 
  ; Allocate memory to read into.
   VarSetCapacity(text, ConWinWidth*ConWinHeight*(A_IsUnicode ? 2 : 1), 0)

   ; Read text.
   if(!DllCall("ReadConsoleOutputCharacter", "PTR", hConOut, "str", text, "uint", ConWinWidth*ConWinHeight, "uint", 0, "PTR*", numCharsRead, "uint"))
   {
      MsgBox ReadConsoleOutputCharacter failed - error %A_LastError%.
      ExitApp
   }

   ; Optional: insert line breaks every %ConWinWidth% characters.
   text := RegExReplace(text, "`a).{" ConWinWidth "}(?=.)", "$0`n")
   text := RegExReplace(text, "^\s+|\s+$")

   DllCall("FreeConsole")
   WinClose, ahk_pid %pid%

   Loop, Parse, text, `n, `r
   {
      If (instr(A_LoopField, "Failed") || instr(A_LoopField, "At Risk"))
      {
         errors = 1
         StringMid, disk, A_LoopField, 16, 1
         break
      }
   }
   If errors = 1
   {
      Menu, Tray, Icon
      Gui,+AlwaysOnTop
      Gui, -MinimizeBox -MaximizeBox
      Gui, Font, s80, Times New Roman
      Gui, Add, Text,, Problema s Raid Disk: %disk%
      Gui, Show,, RaidError
      Gui, +LastFound
      OnMessage(0x112, "WM_SYSCOMMAND")
      Return
   }
   sleep, 3600000
}

WM_SYSCOMMAND(wParam)
{
   if (A_Gui = 1 && wParam = 0xF060) ; SC_CLOSE
      return 0
}

28 (изменено: Malcev, 2014-02-27 13:44:20)

Re: AHK: Как добыть информацию из окна cmd для последующего парсинга

Вот отличный вариант.

#NoTrayIcon
DllCall("AllocConsole")
WinHide % "ahk_id " DllCall("GetConsoleWindow", "ptr")
loop
{
   objShell := ComObjCreate("WScript.Shell")
   objExec := objShell.Exec(ComSpec " /C echo list volume | C:\Windows\System32\diskpart.exe")
   strStdOut := ""
   while, !objExec.StdOut.AtEndOfStream
      strStdOut := objExec.StdOut.ReadAll()
   Loop, Parse, strStdOut, `n, `r
   {
      If (instr(A_LoopField, "Failed") || instr(A_LoopField, "At Risk"))
      {
         errors = 1
         StringMid, disk, A_LoopField, 16, 1
         break
      }
   }
   If errors = 1
   {
      Menu, Tray, Icon
      Gui,+AlwaysOnTop
      Gui, -MinimizeBox -MaximizeBox
      Gui, Font, s80, Times New Roman
      Gui, Add, Text,, Problema s Raid Disk: %disk%
      Gui, Show,, RaidError
      Gui, +LastFound
      OnMessage(0x112, "WM_SYSCOMMAND")
      Return
   }
   sleep, 3600000
}

WM_SYSCOMMAND(wParam)
{
   if (A_Gui = 1 && wParam = 0xF060) ; SC_CLOSE
      return 0
}