[已解决]关于如何读取命令提示符窗口中的内容
本帖最后由 fuinei 于 2011-10-23 13:02 编辑各位好,
请把使用什么函数/方法可读取命令提示符窗口中的内容呢?
测试时使用WinGetText函数无法读取 可以输出后再读取嘛 不知道StdoutRead是不是你想要的 我刚测试了一下好像不行,我希望是运行telnet窗口后,判断其最后是行的信息,如果是Username:则退出程序,否则执行后续操作,请问可以如何实现呢? 给你个代码,自己研究下吧
#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
请问哪位兄弟有简单点的方法?我是autoit新手,太复杂的代码看不太懂。 我也是新手!主要是学习而不是为了代码,哪位高手可以讲解下,不胜感激! 楼上几位,别拿新手来当砝码,人家连代码都给了,autoit帮助也汉化了,一共才不到50行,看不懂的地方查询下帮助,什么都有了。 我是希望了解有没有简单点的函数或UDF可直接获取命令提示符中的内容 我是希望了解有没有简单点的函数或UDF可直接获取命令提示符中的内容 本帖最后由 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: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终端的返回信息。 谢谢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: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 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")