fuinei 发表于 2011-9-23 08:47:22

[已解决]关于如何读取命令提示符窗口中的内容

本帖最后由 fuinei 于 2011-10-23 13:02 编辑

各位好,
    请把使用什么函数/方法可读取命令提示符窗口中的内容呢?
测试时使用WinGetText函数无法读取

autt 发表于 2011-9-23 10:14:11

可以输出后再读取嘛

drunk 发表于 2011-9-23 10:19:26

不知道StdoutRead是不是你想要的

fuinei 发表于 2011-9-23 13:28:23

我刚测试了一下好像不行,我希望是运行telnet窗口后,判断其最后是行的信息,如果是Username:则退出程序,否则执行后续操作,请问可以如何实现呢?

飘云 发表于 2011-9-23 16:51:20

给你个代码,自己研究下吧

#include <GuiConstants.au3>
#include <WindowsConstants.au3>
#include <Constants.au3>
#include <EditConstants.au3>
#include <WindowsConstants.au3>
#include <GUIEdit.au3>
$Form1 = GUICreate("完美回显CMD修订版 by lynfr8", 634, 453, 193, 115)
HotKeySet("{ENTER}", "Testt")
$Edit1 = GUICtrlCreateEdit("", 0, 0, 633, 449)
GUICtrlSetData(-1,@SystemDir & ">")
;GUICtrlSetFont(-1, 8, 400, 0, "Lucida Console")
GUICtrlSetColor(-1, 0xFFFFFF)
GUICtrlSetBkColor(-1, 0x000000)
GUISetState(@SW_SHOW)
Global $array,$array2,$sLastLine = _GUICtrlEdit_GetTextLen($Edit1)

While 1
    Sleep(10)
    _GUICTrlEdit_SetSel($Edit1, _GUICtrlEdit_GetTextLen($Edit1)+1, _GUICtrlEdit_GetTextLen($Edit1)+1)
    $nMsg = GUIGetMsg()
    Switch $nMsg
      Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func Testt ()
    Local $sCmd = StringMid(GUICtrlRead($Edit1), $sLastLine+1)
    _GUICtrlEdit_BeginUpdate($Edit1)
    recall_command($sCmd)
    _GUICtrlEdit_EndUpdate($Edit1)
    _GUICtrlEdit_AppendText($Edit1, @CRLF &@SystemDir & ">")
    Global $sLastLine = _GUICtrlEdit_GetTextLen($Edit1)-UBound($array)-UBound($array2)
EndFunc
   

Func recall_command($info)
    $cmdinfo = Run(@ComSpec & " /c " & $info,@SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD + $STDIN_CHILD)
    While 1
      $line = StdoutRead($cmdinfo)
      If @error Then Return
      If $line = "" Then ContinueLoop
                $array=StringRegExp(GUICtrlRead($Edit1),'[^\x00-\xff]',3)
                $array2=StringRegExp($line,'[^\x00-\xff]',3)
      GUICtrlSetData($Edit1, GUICtrlRead($Edit1)& @CRLF & $line);
    WEnd
EndFunc   ;==>recall_command

fuinei 发表于 2011-9-24 00:00:05

请问哪位兄弟有简单点的方法?我是autoit新手,太复杂的代码看不太懂。

jsgh1983 发表于 2011-9-24 09:21:53

我也是新手!主要是学习而不是为了代码,哪位高手可以讲解下,不胜感激!

bakefish 发表于 2011-9-24 10:10:50

楼上几位,别拿新手来当砝码,人家连代码都给了,autoit帮助也汉化了,一共才不到50行,看不懂的地方查询下帮助,什么都有了。

fuinei 发表于 2011-9-24 10:32:22

我是希望了解有没有简单点的函数或UDF可直接获取命令提示符中的内容

fuinei 发表于 2011-9-24 10:32:25

我是希望了解有没有简单点的函数或UDF可直接获取命令提示符中的内容

netbullking 发表于 2011-9-24 16:05:51

本帖最后由 netbullking 于 2011-9-24 16:09 编辑

飘云 不是已经给出方案了吗!很简单啊
你要的在这个过程:
以下引用 飘云 的代码片段,我给你加了注释
Func recall_command($info)
    ;使用命令提示符窗口运行命令
    $cmdinfo = Run(@ComSpec & " /c " & $info,@SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD + $STDIN_CHILD)

    ;开始无条件循环。目的是再循环中读取命令提示符窗口返回值
    While 1
      ;取命令提示符窗口返回值StdoutRead 是标准函数
      $line = StdoutRead($cmdinfo)
      ;如果出错,返回
      If @error Then Return
      ;如果没有返回值,继续循环
      If $line = "" Then ContinueLoop               
            ......
    WEnd

EndFunc   ;==>recall_command

xiehuahere 发表于 2011-9-25 22:35:17

本帖最后由 xiehuahere 于 2011-9-25 22:36 编辑

Run 只能运行一次telnet并获得telnet登录操作的所有回显,但进入 telnet 窗口后再输入其他命令就无法获取回显了。

所以,如果是telnet的话,建议你看看官网的这个帖子(直接看4楼,会有收获的):
http://www.autoitscript.com/forum/topic/82393-telnet-in-background/page__p__590023#entry590023

思路就是:通过在23端口(telnet端口)建立TCP连接来模拟一个telnet通信,这样此后通过TCPSend()发送的字符就都发送到telnet终端,并且可以通过TCPRecv()来获得telnet终端的返回信息。

fuinei 发表于 2011-9-26 13:13:59

谢谢12楼的建议,目前我只需要进行一次判断即可。
根据11楼的解释和Autoit的汉化帮助,我希望获取telnet后的结果但结果为空,代码如下:
#include <Constants.au3>
$cmdinfo=Run("telnet 192.168.1.1","",@SW_HIDE,$STDERR_CHILD+$STDOUT_CHILD+$STDIN_CHILD)
While 1
    $sResult = StdoutRead($cmdinfo)
    If @error Then ExitLoop
Wend
MsgBox(0, "结果", $sResult)
请问为什么呢?

xiehuahere 发表于 2011-9-26 14:54:42

本帖最后由 xiehuahere 于 2011-9-26 14:56 编辑

这种方式是捕获不到回显的。

StdoutRead() - Reads from the STDOUT stream of a previously run child process.
我的理解:
运行 telnet 192.168.1.1,其实是先telnet,然后内部再起了新进程去open 192.168.1.1。
StdoutRead()只能捕获通过Run方式直接起的那个进程的输出,如果那个进程内部再去起一个新进程(telnet会话),这就没法被捕获了。

官网也是有人问这个问题的,用这种方法最终还是无解。
参见:http://www.autoitscript.com/forum/topic/77269-autoit-can-get-prompt-in-cmd-window/page__p__565064__hl__telnet+execute+__fromsearch__1#entry565064
因为telnet就是个特例。

所以,如果是telnet的话,还是建议用我推荐的方法吧。
给个示例:$host = "192.168.1.1"
$port = 23 ;telnet port

TCPStartup()
$socket = TCPConnect($host, $port)
If $socket = -1 Then
        MsgBox(48, "Error", "Connection fail.")
        Exit
EndIf

Sleep(1000); 如果没获取到,适当加大这个延时
$ack = TCPRecv($socket, 500)
MsgBox(0, "结果", $ack)

TCPCloseSocket($socket)
TCPShutdown()一开始有点乱码,是正常现象。

飘云 发表于 2011-9-26 14:57:52

本帖最后由 飘云 于 2011-9-26 15:00 编辑

Run函数不是这么用的。。。。"telnet 192.168.1.1"如果是命令,那么应该是Run(@ComSpec & " /c " & "telnet 192.168.1.1","", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD + $STDIN_CHILD),如果telnet是一个可执行文件,那么应该是Run("X:\telnet.exe","", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD + $STDIN_CHILD),如果带参数启动,最好用ShellExecute("X:\telnet.exe","192.168.1.1")
页: [1] 2 3
查看完整版本: [已解决]关于如何读取命令提示符窗口中的内容