1

Тема: AHK: Считывание текста из cmd

Приветствую!

По примеру из документации http://www.script-coding.com/AutoHotkey/WinGetText.html пытаюсь вывести текст из cmd. Код таков:


!h::
Run, cmd
WinWait, C:\
sendinput, ping ya.ru {enter}
WinGetText, text
MsgBox, The text is:`n%text%
return

Но на выходе получаю окно с "The text is" и пустым значением переменной.
http://ipic.su/img/img7/fs/kiss_4kb.1354716963.png
Подскажите пожалуйста, почему лыжи не едут?

2 (изменено: creature.ws, 2012-12-05 19:40:24)

Re: AHK: Считывание текста из cmd

Лыжи не едут потому, что из окна консоли нельзя прочитать текст использованием WinGetText
Если цель — узнать, пингуется ли ya.ru, то уместнее воспользоваться примером:

Msgbox % Ping("ya.ru")

Ping(host) {
    (ComObjGet("winmgmts:").ExecQuery("Select StatusCode From Win32_PingStatus where Address = '" . host . "'")._NewEnum)[objStatus]
    return !objStatus.StatusCode
}

3

Re: AHK: Считывание текста из cmd

Оу, всё немного сложнее, чем я думал
Но пинг яндекса я взял в качестве примера. Истинной целью является именно возврат значения из cmd в переменную для дальнейших манипуляций с этим значением.
Подробнее: по одному жмяканью кнопки - телнет на управляемый свич, прописывание нужных команд, считывание результата выполнения команд в переменные, некий анализ содержимого переменных и вывод в msgbox`е результата анализа.  Такая вот автоматизированная минидиагностика.
p.s. если нужно юзать winapi, задумываюсь, а стоит ли тогда на хоткее писать..

4

Re: AHK: Считывание текста из cmd

seemE1y пишет:

p.s. если нужно юзать winapi, задумываюсь, а стоит ли тогда на хоткее писать

Без знания winapi на "хоткее" далеко не уедешь.

CMDret(sCmd)
{
; http://www.autohotkey.com/community/viewtopic.php?f=2&t=16823  StdoutToVar_CreateProcess(sCmd, bStream="", sDir="", sInput="")
/*
    Пример использования:
    MsgBox, % CMDret("cmd /c cd")
*/
   
   DllCall("CreatePipe","Ptr*",hStdInRd
                       ,"Ptr*",hStdInWr
                       ,"Uint",0
                       ,"Uint",0)
   DllCall("CreatePipe","Ptr*",hStdOutRd
                       ,"Ptr*",hStdOutWr
                       ,"Uint",0
                       ,"Uint",0)
   DllCall("SetHandleInformation","Ptr",hStdInRd
                                ,"Uint",1
                                ,"Uint",1)
   DllCall("SetHandleInformation","Ptr",hStdOutWr
                                ,"Uint",1
                                ,"Uint",1)

   if A_PtrSize=4
      {
      VarSetCapacity(pi, 16, 0)
      sisize:=VarSetCapacity(si,68,0)
      NumPut(sisize,    si,  0, "UInt")
      NumPut(0x100,     si, 44, "UInt")
      NumPut(hStdInRd , si, 56, "Ptr")
      NumPut(hStdOutWr, si, 60, "Ptr")
      NumPut(hStdOutWr, si, 64, "Ptr")
      }
   else if A_PtrSize=8
      {
      VarSetCapacity(pi, 24, 0)
      sisize:=VarSetCapacity(si,96,0)
      NumPut(sisize,    si,  0, "UInt")
      NumPut(0x100,     si, 60, "UInt")
      NumPut(hStdInRd , si, 80, "Ptr")
      NumPut(hStdOutWr, si, 88, "Ptr")
      NumPut(hStdOutWr, si, 96, "Ptr")
      }

   DllCall("CreateProcess", "Uint", 0
                           , "Ptr", &sCmd
                          , "Uint", 0
                          , "Uint", 0
                           , "Int", True
                          , "Uint", 0x08000000
                          , "Uint", 0
                          , "Uint", 0
                           , "Ptr", &si
                           , "Ptr", &pi)

   DllCall("CloseHandle","Ptr",NumGet(pi,0))
   DllCall("CloseHandle","Ptr",NumGet(pi,A_PtrSize))
   DllCall("CloseHandle","Ptr",hStdOutWr)
   DllCall("CloseHandle","Ptr",hStdInRd)
   DllCall("CloseHandle","Ptr",hStdInWr)

   VarSetCapacity(sTemp,4095)
   nSize:=0
   loop
      {
      result:=DllCall("Kernel32.dll\ReadFile", "Uint", hStdOutRd
                                             ,  "Ptr", &sTemp
                                             , "Uint", 4095
                                             ,"UintP", nSize
                                              ,"Uint", 0)
      if (result="0")
         break
      else
         sOutput:= sOutput . StrGet(&sTemp,nSize,"CP866")
      }

   DllCall("CloseHandle","Ptr",hStdOutRd)
   Return,sOutput
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

5

Re: AHK: Считывание текста из cmd

спасибо за пример, буду разбираться, правда без комментов новичку сложновато

6 (изменено: creature.ws, 2012-12-05 21:12:56)

Re: AHK: Считывание текста из cmd

Комментарий:
Функция CMDret возвращает «результат выполнения» консольной команды переданной в виде строки в качестве параметра.
Разбираться нет необходимости, достаточно использовать.

Тот же код:

msgbox % CMDret("ping ya.ru")

CMDret(sCmd)
{
    DllCall("CreatePipe", "Ptr*", hStdInRd, "Ptr*", hStdInWr, "Uint", 0, "Uint", 0)
    DllCall("CreatePipe", "Ptr*", hStdOutRd, "Ptr*", hStdOutWr, "Uint", 0, "Uint", 0)
    DllCall("SetHandleInformation", "Ptr", hStdInRd, "Uint", 1, "Uint", 1)
    DllCall("SetHandleInformation", "Ptr", hStdOutWr,"Uint", 1, "Uint", 1)

    if A_PtrSize = 4
    {
        VarSetCapacity(pi, 16, 0)
        siSize := VarSetCapacity(si, 68, 0)
        NumPut(siSize, si, 0, "UInt")
        NumPut(0x100, si, 44, "UInt")
        NumPut(hStdInRd , si, 56, "Ptr")
        NumPut(hStdOutWr, si, 60, "Ptr")
        NumPut(hStdOutWr, si, 64, "Ptr")
    }
    else if A_PtrSize = 8
    {
        VarSetCapacity(pi, 24, 0)
        siSize := VarSetCapacity(si, 96, 0)
        NumPut(siSize, si, 0, "UInt")
        NumPut(0x100, si, 60, "UInt")
        NumPut(hStdInRd , si, 80, "Ptr")
        NumPut(hStdOutWr, si, 88, "Ptr")
        NumPut(hStdOutWr, si, 96, "Ptr")
    }

    DllCall("CreateProcess"
        , "Uint", 0
        , "Ptr", &sCmd
        , "Uint", 0
        , "Uint", 0
        , "Int", true
        , "Uint", 0x08000000
        , "Uint", 0
        , "Uint", 0
        , "Ptr", &si
        , "Ptr", &pi)

    DllCall("CloseHandle", "Ptr", NumGet(pi, 0))
    DllCall("CloseHandle", "Ptr", NumGet(pi, A_PtrSize))
    DllCall("CloseHandle", "Ptr", hStdOutWr)
    DllCall("CloseHandle", "Ptr", hStdInRd)
    DllCall("CloseHandle", "Ptr", hStdInWr)

    VarSetCapacity(sTemp, 4095)

    while DllCall("Kernel32.dll\ReadFile", "Uint", hStdOutRd, "Ptr", &sTemp, "Uint", 4095, "UintP", nSize, "Uint", 0)
        sOutput := sOutput . StrGet(&sTemp, nSize, "CP866")

    DllCall("CloseHandle", "Ptr", hStdOutRd)

    return sOutput
}