Jump to content
Sign in to follow this  
remmo

Unable to read text from a java-based telnet application

Recommended Posts

remmo

Hello everyone.

I want to automate a telnet session, but that automation needs to "know" if some specific text is displayed within the session in order to make certain decisions.

The telnet client is Ivory vcEmulator, which I think is a Java-based application.

I use the AutoitWindow Info to check if Autoit is able to read the text inside the session window, but no luck at all.

The information available from that window is the title, the class (Class: SunAwtFrame), the size, the position, the Style (0x16CF0000), the ExStyle (0x00000100) and the Handle (0x00810FFE).

Any ideas??

Thanks in advance.

Share this post


Link to post
Share on other sites
Chimp

hi remmo,

welcome to the forum :)

I had the same problem, and solved it using this telnet console instead.

here is a simple example that shows how to use it with autoit.
of course you have to use proper commands for the terminal you want to connect to.

#include <Constants.au3>
#include <array.au3>
#autoit3wrapper_usex64=n ; runs the script in 32 bit program mode

; http://www.autoitscript.com/forum/topic/148340-solvedhow-run-a-telnet-from-script/?hl=%2Btelnet#entry1054557
; Use False to disable redirection, it will only apply to the program if running as 32 bit process
_Wow64FsRedirection(False)
Global $tn = Run(".\telnet\telnet.exe", ".\telnet", @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)
_Wow64FsRedirection(True)

If Not $tn Then
    ConsoleWrite("!Error starting Telnet. (error " & @error & ") End.")
    Exit
EndIf

Local $_buffer
Local $TermIP = "10.0.1.2" ; terminal to connect

Sleep(2000) ; wait a moment

; waiting telnet prompt
While Not StringInStr(_ReadTerminal($tn), "telnet>", 2, -1) ; is prompt ready?
    Sleep(500)
WEnd
; ConsoleWrite("ok. received telnet ""prompt""." & @CRLF)

StdinWrite($tn, "open " & $TermIP & @CR) ; <== use proper command to connect to your terminal

While Not StringInStr(_ReadTerminal($tn), "Enter password please:", 2) ; wait rq pwd string
    Sleep(500)
WEnd
; ConsoleWrite("ok. password request received"&@CRLF)

StdinWrite($tn, "Password" & @CR) ; <=== send password

StdinWrite($tn, "YourCommandToSend" & @CR) ; <=== use statements like this to send proper commands to the remote terminal

While 1 ; <=== in this loop you get the output from terminal

    $BufferData = _ReadTerminal($tn)

    ; do here what you want with received data

    ; this sequence at the end of the received string means end of otput of the command sent
    ; this is ok in my case, you have to check if is true also for your terminal
    If StringRight($BufferData, 4) = Chr(13) & Chr(10) & Chr(36) & Chr(32) Then ; waiting the $
        ExitLoop
    EndIf
    Sleep(500)
WEnd

StdinWrite($tn, "logout" & @CR) ; <== you exit from session
ProcessClose($tn) ; closes "Telnet.exe"
ConsoleWrite("The end" & @CRLF)

; - - - - - the end - - - - -

; http://www.autoitscript.com/forum/topic/111647-macro-problem-in-win7-x64/#entry790037
Func _Wow64FsRedirection($state)
    ; Disables or reverts the filesystem redirector for a 32 bit process running on 64bit OS
    If Not @AutoItX64 And @OSArch = 'X64' Then
        If $state Then
            DllCall("kernel32.dll", "int", "Wow64RevertWow64FsRedirection", "int", 0)
        Else
            DllCall("kernel32.dll", "int", "Wow64DisableWow64FsRedirection", "int", 0); or 1 as per help
        EndIf
        If @error Then Return SetError(1)
    EndIf
EndFunc   ;==>_Wow64FsRedirection

; retrieves the output from the terminal
Func _ReadTerminal($Terminal)
    Local $sRecv = ""
    Local $RecvBuffer = ""

    $sRecv = StdoutRead($Terminal, False, False) ; first part of receiving data goes in $Recv (if any)
    While 1 ; read more data if available
        $RecvBuffer = StdoutRead($Terminal, False, False) ; is there more data ?
        If $RecvBuffer = "" Then ; <--- if no more data to read then exit
            ExitLoop
        EndIf
        $sRecv = $sRecv & $RecvBuffer; append new data to $Recv
        ; !!! if a very (too) long message is received then autoit goes out of memory here !!!
        ; do to: chech if overflow then truncate input and disconnect client
        Sleep(10)
    WEnd
    ; remove chr(0) if present otherwise data following the 0 is lost
    ConsoleWrite(StringReplace($sRecv, Chr(0), "") & @CRLF)
    Return $sRecv
EndFunc   ;==>_ReadTerminal

I hope it can do

bye

 

 


small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
remmo

hi remmo,

welcome to the forum :)

I had the same problem, and solved it using this telnet console instead.

here is a simple example that shows how to use it with autoit.

of course you have to use proper commands for the terminal you want to connect to.

#include <Constants.au3>
#include <array.au3>
#autoit3wrapper_usex64=n ; runs the script in 32 bit program mode

; http://www.autoitscript.com/forum/topic/148340-solvedhow-run-a-telnet-from-script/?hl=%2Btelnet#entry1054557
; Use False to disable redirection, it will only apply to the program if running as 32 bit process
_Wow64FsRedirection(False)
Global $tn = Run(".\telnet\telnet.exe", ".\telnet", @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)
_Wow64FsRedirection(True)

If Not $tn Then
    ConsoleWrite("!Error starting Telnet. (error " & @error & ") End.")
    Exit
EndIf

Local $_buffer
Local $TermIP = "10.0.1.2" ; terminal to connect

Sleep(2000) ; wait a moment

; waiting telnet prompt
While Not StringInStr(_ReadTerminal($tn), "telnet>", 2, -1) ; is prompt ready?
    Sleep(500)
WEnd
; ConsoleWrite("ok. received telnet ""prompt""." & @CRLF)

StdinWrite($tn, "open " & $TermIP & @CR) ; <== use proper command to connect to your terminal

While Not StringInStr(_ReadTerminal($tn), "Enter password please:", 2) ; wait rq pwd string
    Sleep(500)
WEnd
; ConsoleWrite("ok. password request received"&@CRLF)

StdinWrite($tn, "Password" & @CR) ; <=== send password

StdinWrite($tn, "YourCommandToSend" & @CR) ; <=== use statements like this to send proper commands to the remote terminal

While 1 ; <=== in this loop you get the output from terminal

    $BufferData = _ReadTerminal($tn)

    ; do here what you want with received data

    ; this sequence at the end of the received string means end of otput of the command sent
    ; this is ok in my case, you have to check if is true also for your terminal
    If StringRight($BufferData, 4) = Chr(13) & Chr(10) & Chr(36) & Chr(32) Then ; waiting the $
        ExitLoop
    EndIf
    Sleep(500)
WEnd

StdinWrite($tn, "logout" & @CR) ; <== you exit from session
ProcessClose($tn) ; closes "Telnet.exe"
ConsoleWrite("The end" & @CRLF)

; - - - - - the end - - - - -

; http://www.autoitscript.com/forum/topic/111647-macro-problem-in-win7-x64/#entry790037
Func _Wow64FsRedirection($state)
    ; Disables or reverts the filesystem redirector for a 32 bit process running on 64bit OS
    If Not @AutoItX64 And @OSArch = 'X64' Then
        If $state Then
            DllCall("kernel32.dll", "int", "Wow64RevertWow64FsRedirection", "int", 0)
        Else
            DllCall("kernel32.dll", "int", "Wow64DisableWow64FsRedirection", "int", 0); or 1 as per help
        EndIf
        If @error Then Return SetError(1)
    EndIf
EndFunc   ;==>_Wow64FsRedirection

; retrieves the output from the terminal
Func _ReadTerminal($Terminal)
    Local $sRecv = ""
    Local $RecvBuffer = ""

    $sRecv = StdoutRead($Terminal, False, False) ; first part of receiving data goes in $Recv (if any)
    While 1 ; read more data if available
        $RecvBuffer = StdoutRead($Terminal, False, False) ; is there more data ?
        If $RecvBuffer = "" Then ; <--- if no more data to read then exit
            ExitLoop
        EndIf
        $sRecv = $sRecv & $RecvBuffer; append new data to $Recv
        ; !!! if a very (too) long message is received then autoit goes out of memory here !!!
        ; do to: chech if overflow then truncate input and disconnect client
        Sleep(10)
    WEnd
    ; remove chr(0) if present otherwise data following the 0 is lost
    ConsoleWrite(StringReplace($sRecv, Chr(0), "") & @CRLF)
    Return $sRecv
EndFunc   ;==>_ReadTerminal

I hope it can do

bye

 

Thank you so much for your help and for your time.

Sadly, for security reasons and compatibility between the client and the host, I cannot use any other telnet client.

Also, the Console Telnet installer (the link you provided) doesn't seems to work with Windows 7 x64.

However, the Ivory vcEmulator window supports text selection using the mouse, and also it can copy to clippboard the selected text, so maybe the best approach for me is:

1)- Check is the application is running

2)- Identify the size and the position of the window in the screen

3)- Simulate the mouse movement over the screen and the text selection across the window

4)- Copy the selected text to the clippboard, and from that point, check for the string I'm looking for.

Obviously, that is not the most elegant solution, since the computer must be always logged-on, but right know, no other way comes to my mind :

Edited by remmo

Share this post


Link to post
Share on other sites
Chimp

hi remmo,

to use the telnet client that I have suggested, it is not necessary to run the installer, you can simply extract the contents to a folder and use the executable directly from there. I use it without problems on Win7 x64.

however, if you have to use your java client then you can try this:
1) Run your telnet client
2) execute this script first and then move the mouse over the screen area you want to copy, and make a note of the coordinates x1, y1 (upper left corner), x2, y2 (bottom right corner)
3) click outside of the telnet client to close this script

WinActivate("[Class:SunAwtFrame]")
AutoItSetOption("MouseCoordMode", 2) ; relative coords to the client area of the active window
Do
    Local $pos = MouseGetPos()
    ConsoleWrite("Mouse x,y: " & $pos[0] & "," & $pos[1] & @CRLF)
    Sleep(300)
Until Not WinActive("[Class:SunAwtFrame]")
AutoItSetOption("MouseCoordMode", Default) ; reset to default coords mode

once you have taken note of the coordinates of the area you want to copy to the clipboard, try this second scrip, setting in advance the variables $x1, $y1, $x2, $y2 with the values ​​that you noted previously.

$x1 = 5 ; change this variables accordingly
$y1 = 5
$x2 = 50
$y2 = 50

WinActivate("[Class:SunAwtFrame]")
AutoItSetOption("MouseCoordMode", 2) ; relative coords to the client area of the active window
SendKeepActive("[Class:SunAwtFrame]")
MouseClickDrag("left", $x1, $y1, $x2, $y2, 0)
Send("^c") ; send a control-c to copy selected text to clipboard
SendKeepActive("")
AutoItSetOption("MouseCoordMode", Default) ; reset to default

Local $bak = ClipGet() ; the content of clipboard goes to the $bak variable

This second script should copy the content of the screen area (text) of your choice into the clipboard.

is not a "state of the art" of programming but it should work for a first step :)
 
good luck

EDIT

Of course the first script is used only once, the first time only to find the coordinates necessary to the second script, then it is not needed it anymore.

Edited by Pincopanco

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
dbs179

hi remmo,

welcome to the forum :)

I had the same problem, and solved it using this telnet console instead.

here is a simple example that shows how to use it with autoit.

of course you have to use proper commands for the terminal you want to connect to.

#include <Constants.au3>
#include <array.au3>
#autoit3wrapper_usex64=n ; runs the script in 32 bit program mode

; http://www.autoitscript.com/forum/topic/148340-solvedhow-run-a-telnet-from-script/?hl=%2Btelnet#entry1054557
; Use False to disable redirection, it will only apply to the program if running as 32 bit process
_Wow64FsRedirection(False)
Global $tn = Run(".\telnet\telnet.exe", ".\telnet", @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)
_Wow64FsRedirection(True)

If Not $tn Then
    ConsoleWrite("!Error starting Telnet. (error " & @error & ") End.")
    Exit
EndIf

Local $_buffer
Local $TermIP = "10.0.1.2" ; terminal to connect

Sleep(2000) ; wait a moment

; waiting telnet prompt
While Not StringInStr(_ReadTerminal($tn), "telnet>", 2, -1) ; is prompt ready?
    Sleep(500)
WEnd
; ConsoleWrite("ok. received telnet ""prompt""." & @CRLF)

StdinWrite($tn, "open " & $TermIP & @CR) ; <== use proper command to connect to your terminal

While Not StringInStr(_ReadTerminal($tn), "Enter password please:", 2) ; wait rq pwd string
    Sleep(500)
WEnd
; ConsoleWrite("ok. password request received"&@CRLF)

StdinWrite($tn, "Password" & @CR) ; <=== send password

StdinWrite($tn, "YourCommandToSend" & @CR) ; <=== use statements like this to send proper commands to the remote terminal

While 1 ; <=== in this loop you get the output from terminal

    $BufferData = _ReadTerminal($tn)

    ; do here what you want with received data

    ; this sequence at the end of the received string means end of otput of the command sent
    ; this is ok in my case, you have to check if is true also for your terminal
    If StringRight($BufferData, 4) = Chr(13) & Chr(10) & Chr(36) & Chr(32) Then ; waiting the $
        ExitLoop
    EndIf
    Sleep(500)
WEnd

StdinWrite($tn, "logout" & @CR) ; <== you exit from session
ProcessClose($tn) ; closes "Telnet.exe"
ConsoleWrite("The end" & @CRLF)

; - - - - - the end - - - - -

; http://www.autoitscript.com/forum/topic/111647-macro-problem-in-win7-x64/#entry790037
Func _Wow64FsRedirection($state)
    ; Disables or reverts the filesystem redirector for a 32 bit process running on 64bit OS
    If Not @AutoItX64 And @OSArch = 'X64' Then
        If $state Then
            DllCall("kernel32.dll", "int", "Wow64RevertWow64FsRedirection", "int", 0)
        Else
            DllCall("kernel32.dll", "int", "Wow64DisableWow64FsRedirection", "int", 0); or 1 as per help
        EndIf
        If @error Then Return SetError(1)
    EndIf
EndFunc   ;==>_Wow64FsRedirection

; retrieves the output from the terminal
Func _ReadTerminal($Terminal)
    Local $sRecv = ""
    Local $RecvBuffer = ""

    $sRecv = StdoutRead($Terminal, False, False) ; first part of receiving data goes in $Recv (if any)
    While 1 ; read more data if available
        $RecvBuffer = StdoutRead($Terminal, False, False) ; is there more data ?
        If $RecvBuffer = "" Then ; <--- if no more data to read then exit
            ExitLoop
        EndIf
        $sRecv = $sRecv & $RecvBuffer; append new data to $Recv
        ; !!! if a very (too) long message is received then autoit goes out of memory here !!!
        ; do to: chech if overflow then truncate input and disconnect client
        Sleep(10)
    WEnd
    ; remove chr(0) if present otherwise data following the 0 is lost
    ConsoleWrite(StringReplace($sRecv, Chr(0), "") & @CRLF)
    Return $sRecv
EndFunc   ;==>_ReadTerminal

I hope it can do

bye

PincoPanco,

Your solution to Telnet issues seems the best I've seen so far, but I'm having issues when i run  Console Telnet using $STDIN_CHILD + $STDOUT_CHILD.  If I use those options I never get the telnet> prompt, only a blank Console Telnet window (I modified your example to @SW_SHOW so I could step through the process).  If I remove $STDIN_CHILD + $STDOUT_CHILD the telnet prompt shows up as it should with the telnet> prompt.  What am I missing or doing wrong here?

 

Thanks,

Dave

Edited by dbs179

Share this post


Link to post
Share on other sites
Chimp

Hi  dbs179
to interact programmatically with the telnet program, you have to redirect telnet's i/o streams using $STDIN_CHILD + $STDOUT_CHILD parameters.
unfortunately doing so you will lose the possibility to see visually what is going on on the black window of the telnet program that is on the screen. for this reason is better to also use the @sw_hide parameter, so you haven't an needless black window on the screen.

instead, all the telnet session must be managed programmatically via i/o streams.
(have a look to >this post for some example about redirection.)

in the >above telnet example, the waiting of the telnet> prompt is performed by this code:

; waiting telnet prompt
While Not StringInStr(_ReadTerminal($tn), "telnet>", 2, -1) ; is prompt ready?
    Sleep(500)
WEnd

and when the prompt is detected, the script goes ahead.

By using I/O redirection you are left on you own, and you have to manage everything by your code.

You have to know exactly how to react to everything incoming from the  StdoutRead() stream .....(it seems not easy, but it isn't difficult :))

P.S.

Give a look also >here for an example on how to "tail" the StdoutRead() to simulate the lack of the "black window output" of the telnet window.

 

 

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
dbs179

Pinco,

Thank you for explaining that so well.  It made sense and now that I've looked at your example using a DOS command it makes more sense.  I was able to manipulate the dos example to do a simple ping to localhost and return a success message box.  I noticed how all of the Ping information that would have normally showed up in the DOS window were passed to the AutoIT console as you said.  I am still having issues with the telnet example though.  I've removed the ; from the ConsoleWrite line below to see if I was detecting the telnet prompt, but I still never see in the console that the telnet prompt is ready.  If I can get to that point, I think I can work it out from there, but I'm not sure why StringInStr is not picking up the prompt and moving forward.

Thanks again for any help.  I appreciate it

Dave

; waiting telnet prompt
While Not StringInStr(_ReadTerminal($tn), "telnet>", 2, -1) ; is prompt ready?
    Sleep(500)
WEnd
ConsoleWrite("ok. received telnet ""prompt""." & @CRLF)

Share this post


Link to post
Share on other sites
Chimp

as I have seen ?do=embed' frameborder='0' data-embedContent>>in this post, you have found the right answer to your problem.

as a reference To help other people that may have your same issue, and if it is not needed a true and intensive telnet traffic, but instead just a simple connection test to a remote device, then consider ?do=embed' frameborder='0' data-embedContent>>this simpler solution without wasting time to setup and configure "telnet console"

but if you need to use "telnet console", then also have a look >here for suggestion to setup.


small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
glakra

Hello Guys,

I am new to autoit. I want  to run a program called PrinterInfo.exe, search for the the specific word " STATUS_PAPEROUT", if found then send email to desired recipient.

So far I have only able to run program, take a window capture save the window capture and then email the window capture to the recipient. But this is not what i want.

I have read posts which suggest that I should use WinGetText to retrieve the word, however I have still no idea as to how to search for the specific word " STATUS_PAPEROUT" and if present then send email.

Please help

Share this post


Link to post
Share on other sites
Chimp

Hi glakra

you are too vague about the PrinterInfo.exe program,

please, give more info about the PrinterInfo.exe program or provide a link to where to find info about it.

thanks


small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×