Jump to content

Telnet, the question that has been asked 1000 times


 Share

Recommended Posts

Hi all,

I have looked and looked, but still can't find a suitable way to make this work right. I have the script working the way I want it, but I am using a sloppy way of doing it. I am trying to write small utility used to program serial to network adapters. All of which we program using arp and telnet. I have the arp portion figured out no problem, but when it comes to telnet I am getting stumped. I can launch the telnet session and connect no problem, but I then need to select several different options, to load the static IP, set the default gateway and so on. Right now I am doing this using Send, Enter and Sleeping until the telnet session moves onto the next prompt. It is not very reliable this way. I am hoping one of you can guide me to the right solution. I did read the StdoutRead example and help file, but I'm not sure it will work here. Below is an example of what I need to do. If there is anyway at all to get the prompt that is in the Telnet Session and compare it to what I am expecting that would awesome. I'm not even a beginner at this, so please take it easy on me if this has been solved before.

Thanks in advance

Dave

If GUICtrlRead($SDS_1101_RADIO_BUTTON) = 1 Then
                            _RunDOS('start telnet ' &$DEV_IPADD& ' 1');Runs Telnet with Port of 1
                            WinActivate("Telnet " & $DEV_IPADD)
                            WinWaitClose("Telnet " & $DEV_IPADD)
                            _RunDOS('start telnet ' &$DEV_IPADD& ' 9999');Runs Telnet with Port of 9999
                            WinActivate("Telnet " & $DEV_IPADD)
                            WinWaitActive("Telnet " & $DEV_IPADD)
                            Send("{ENTER}");Enter to go into Programming
                            Sleep(500)
                            Send("0");0 to Enter IP Configuration
                            Sleep(500)
                            Send("{ENTER}");Enter to Enter IP Configuration
                            Sleep(500)
                            Send($DEV_IPADD);Inputs IP Address
                            Sleep(500)
                            Send("{ENTER}");Moves to Next Option
                            Sleep(500)
                            Send("Y");Yes to Change Gateway
                            Sleep(500)
                            Send($DEV_GATEWAY);Inputs Gateway
                            Sleep(500)
                            Send("{ENTER}");Moves to Next Option
                            Sleep(700)
                                If $DEV_SUBNET = "255.0.0.0" Then;If Statments for Subnet Mask Settings
                                Send("24")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.128.0.0" Then;If Statments for Subnet Mask Settings
                                Send("23")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.192.0.0" Then;If Statments for Subnet Mask Settings
                                Send("22")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.224.0.0" Then;If Statments for Subnet Mask Settings
                                Send("21")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.240.0.0" Then;If Statments for Subnet Mask Settings
                                Send("20")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.248.0.0" Then;If Statments for Subnet Mask Settings
                                Send("19")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.252.0.0" Then;If Statments for Subnet Mask Settings
                                Send("18")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.254.0.0" Then;If Statments for Subnet Mask Settings
                                Send("17")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.255.0.0" Then;If Statments for Subnet Mask Settings
                                Send("16")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.255.128.0" Then;If Statments for Subnet Mask Settings
                                Send("15")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.255.192.0" Then;If Statments for Subnet Mask Settings
                                Send("14")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.255.224.0" Then;If Statments for Subnet Mask Settings
                                Send("13")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.255.240.0" Then;If Statments for Subnet Mask Settings
                                Send("12")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.255.248.0" Then;If Statments for Subnet Mask Settings
                                Send("11")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.255.252.0" Then;If Statments for Subnet Mask Settings
                                Send("10")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.255.254.0" Then;If Statments for Subnet Mask Settings
                                Send("09")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.255.255.0" Then;If Statments for Subnet Mask Settings
                                Send("08")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.255.255.128" Then;If Statments for Subnet Mask Settings
                                Send("07")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.255.255.192" Then;If Statments for Subnet Mask Settings
                                Send("06")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.255.255.224" Then;If Statments for Subnet Mask Settings
                                Send("05")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.255.255.240" Then;If Statments for Subnet Mask Settings
                                Send("04")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.255.255.248" Then;If Statments for Subnet Mask Settings
                                Send("03")
                                Sleep(500)
                                Send("{ENTER}")
                                ElseIf $DEV_SUBNET = "255.255.255.252" Then;If Statments for Subnet Mask Settings
                                Send("02")
                                Sleep(500)
                                Send("{ENTER}")
                                Else
                                Send("0")
                                Sleep(500)
                                Send("{ENTER}")
                                Sleep(500)
                                EndIf
                            Send("N");Change Telnet Password
                            Sleep(500)
                            Send("1");Return to Main Menu - Channel 1 Configuration
                            Sleep(500)
                            Send("{ENTER}")
                            Sleep(500)
                            Send("38400");Set Baud Rate
                            Sleep(500)
                            Send("{ENTER}")
                            Sleep(500)
                            Send("4C");Set I/F Mode
                            Sleep(500)
                            Send("{ENTER}")
                            Sleep(500)
                            Send("02");Set Flow Control
                            Sleep(500)
                            Send("{ENTER}")
                            Sleep(500)
                            Send("3001");Set Port Number
                            Sleep(500)
                            Send("{ENTER}")
                            Sleep(500)
                            Send("C0");Set Connect Mode
                            Sleep(500)
                            Send("{ENTER}");Send +++ in Modem Mode
                            Sleep(500)
                            Send("{ENTER}");Show IP After Ring
                            Sleep(500)
                            Send("{ENTER}");Auto Increment
                            Sleep(500)
                            Send("{ENTER}");Remote IP Address Octet 1
                            Sleep(500)
                            Send("{ENTER}");Remote IP Address Octet 2
                            Sleep(500)
                            Send("{ENTER}");Remote IP Address Octet 3
                            Sleep(500)
                            Send("{ENTER}");Remote IP Address Octet 4
                            Sleep(500)
                            Send("{ENTER}");Remote Port
                            Sleep(500)
                            Send("{ENTER}");Disconnect Mode
                            Sleep(500)
                            Send("{ENTER}");Flush Mode
                            Sleep(500)
                            Send("{ENTER}");Disconnect Time Hour
                            Sleep(500)
                            Send("{ENTER}");Disconnect Time Minute
                            Sleep(500)
                            Send("{ENTER}");Send Char 1
                            Sleep(500)
                            Send("{ENTER}");Send Char 2
                            Sleep(500)
                            Send("{ENTER}");Return to Main Menu
                            Sleep(500)
                            Send("9");Save and Exit
                            Sleep(500)
                            Send("{ENTER}");Send Save and Exit
                            Sleep(2000)
                            Send("{ENTER}")
                        _GUICtrlEdit_AppendText($UP_STATUS_WINDOW, @CRLF & "SDS100 Successfully Programmed.")
                        EndIf
Link to comment
Share on other sites

@dbs179

I know very well what your problem is, I had that problem myself and worked hard to make an application to configure switches using either the serial interface or telnet.

I've discovered that I can't use telnet to do this because of the over-complicated way to retrieve the prompt and the messages returned; this copy-paste of info and string splitting/searching/matching is much too complicated to work efficiently.

I know of 2 ways to do this:

- use of TeraTerm, a free application able to handle serial communication and telnet/ssh. Its big advantage over Telnet is the fact that this application has a very powerful log feature. When the log is activated every bit of information on the screen is written to the log in real-time; this way you don't need to copy-paste info but you only need to search the log file. You have to keep track of the last log line number and everything is easy after that.

At some point you know that the last entry in the log - the prompt - is line 10, you enter your command, you get something in return (answer or error message ...) and the prompt will come back to you on the very last line of the log. The new last line will be then number 12, all you have to do is to get the text between line 10 and 12 and look for keywords. (the numbers are only an example)

Telnet can generate a log if you redirect the output to a text file BUT it never updates the log in real-time so you can't use that for your purpose.

There are some disadvantages of using a 3rd party application (be it telnet or TeraTerm or other) - you have to use "Send" commands to that application window therefore that window has to be active; that might not be possible all the time.

- use of a COM/ActiveX object to build your own telnet-like application. I have found one WOD Telnet which doesn't cost much (1 developer license is 199 USD).

They have a trial version (for 30 days) and they are willing to extend it if you ask them. It is a very well-built piece of software and easy to use it to build a telnet application. I had tested it and it didn't take me more to get what I needed from it.

The big advantage of this solution is: you have it integrated in your application and you work with it directly (no more Send, WinActive ... and other stuff)

It is up to you which solution to use. I wish you good luck.

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Link to comment
Share on other sites

@dbs179

I know very well what your problem is, I had that problem myself and worked hard to make an application to configure switches using either the serial interface or telnet.

I've discovered that I can't use telnet to do this because of the over-complicated way to retrieve the prompt and the messages returned; this copy-paste of info and string splitting/searching/matching is much too complicated to work efficiently.

I know of 2 ways to do this:

- use of TeraTerm, a free application able to handle serial communication and telnet/ssh. Its big advantage over Telnet is the fact that this application has a very powerful log feature. When the log is activated every bit of information on the screen is written to the log in real-time; this way you don't need to copy-paste info but you only need to search the log file. You have to keep track of the last log line number and everything is easy after that.

At some point you know that the last entry in the log - the prompt - is line 10, you enter your command, you get something in return (answer or error message ...) and the prompt will come back to you on the very last line of the log. The new last line will be then number 12, all you have to do is to get the text between line 10 and 12 and look for keywords. (the numbers are only an example)

Telnet can generate a log if you redirect the output to a text file BUT it never updates the log in real-time so you can't use that for your purpose.

There are some disadvantages of using a 3rd party application (be it telnet or TeraTerm or other) - you have to use "Send" commands to that application window therefore that window has to be active; that might not be possible all the time.

- use of a COM/ActiveX object to build your own telnet-like application. I have found one WOD Telnet which doesn't cost much (1 developer license is 199 USD).

They have a trial version (for 30 days) and they are willing to extend it if you ask them. It is a very well-built piece of software and easy to use it to build a telnet application. I had tested it and it didn't take me more to get what I needed from it.

The big advantage of this solution is: you have it integrated in your application and you work with it directly (no more Send, WinActive ... and other stuff)

It is up to you which solution to use. I wish you good luck.

enaiman,

Thanks for your response, not only does it answer my question, but it was very concise and easy to understand. I don't think using your second option will work for me. I am not very savvy at these sort of things and don't think I have the skills to pull off creating my own telnet-like app as you describe. However, I am going to check out Tera-Term, it should work for what I need. I do see the downside of this solution, but think for what I am doint, it should work fine.

Thanks again for all of the responses.

Dave

Link to comment
Share on other sites

Telnet knows a thing or two. >_< Just type "telnet -?" and see the "-f filename" entry. A perfect realtime logging. :)

Here a sample: "telnet -f telnet.log 127.0.0.1"

Don't forget to close and open the file to get new records.

just my 2 cents. :idiot:

Hubertus,

Are you saying that with Telnet -f I can do the same thing? I will just have to open and close the log file to see new entries? If so that is another good option that won't require the install of Tera Term.

enaiman,

I got Tera Term and have it connecting in my script, but I can't figure out a good way to start the logging. I didn't see any keyboard shortcuts to start it and don't want to rely on Mouse Clicks by coordinates. I didn't see any control ID's either. I saw that you can set custom shortcuts with Tera Term. Is that how you start logging, or am I missing something simple? Also, I can't quite figure out how to edit the keyboard file to set up a shortcut....

Thanks again both of you for the help.

Dave

Edited by dbs179
Link to comment
Share on other sites

Just had sparetime to code a working sample:

; Script to demonstrate trapping of telnet output. Written by hubertus72.
; Sample using SMTP server (port 587) since no public telnet server known.
$Telnetserver = "smtp.gmx.net 587"
Global $Filename = @ScriptFullPath & ".telnet.log"

Opt("OnExitFunc","Terminate")
HotKeySet("{ESC}","ESC")
Func ESC()
Exit MsgBox(0, "Telnet sample finished", "Telnet sample finished by ESC",2)
EndFunc
Func terminate()
WinClose("[last]")
FileDelete($Filename)
Exit MsgBox(0, "Telnet sample finished", "Telnet sample ended.",5)
EndFunc

$Cmd = @ComSpec & " /k " & 'telnet -f "' & $Filename & '" ' & $Telnetserver
$pid = Run($Cmd)
If @error Then Exit MsgBox(0, "Error PID", $pid)
WinWaitActive("[REGEXPTITLE:Telnet ]")
ControlSend("[last]", "", "", "Helo")
While Sleep(200)
    $data = FileRead($Filename)
    MsgBox(0, "Press ESC to terminate ...", $data, 2)
    ControlSend("[last]", "", "", "Time: " & @YEAR & "." & @MON & "." & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & "{enter}")
WEnd

enjoy :)

Edit: changed fileread line to use variable $filename

Awesome. What you have is way beyond my capabilities (I really just know enough to screw things up), But I think I can dissect it and make sense of it all. I'll let you know if it works out for me.

Thanks again for the help. I really do appreciate it.

Dave

Link to comment
Share on other sites

Telnet knows a thing or two. :( Just type "telnet -?" and see the "-f filename" entry. A perfect realtime logging. :P

Here a sample: "telnet -f telnet.log 127.0.0.1"

Don't forget to close and open the file to get new records.

just my 2 cents. :idea:

It somehow works but - it never shows the current prompt and that is bad enough if the current prompt tells you that a command has finished its execution. The prompt is very important because it tells me when I should send the next command (I don't have to use Sleep between commands because some commands are executed instantly while others might take 30 seconds or even 1 or 2 minutes) and that is very important. TeraTerm shows the prompt and that's why I found it very useful.

I'll try to put together a small example about using TeraTerm.

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiIPAddress.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

Opt("GUIOnEventMode", 1)
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 171, 191, 193, 125)
GUISetOnEvent($GUI_EVENT_CLOSE, "Form1Close")
$IPAddress1 = _GUICtrlIpAddress_Create($Form1, 13, 30, 146, 26)
_GUICtrlIpAddress_Set($IPAddress1, "192.168.0.22")
$Label1 = GUICtrlCreateLabel("Remote IP", 13, 10, 54, 17)
$UName = GUICtrlCreateInput("username", 13, 85, 146, 21, BitOR($ES_CENTER,$ES_AUTOHSCROLL))
$pwd = GUICtrlCreateInput("password", 13, 116, 146, 21, BitOR($ES_CENTER,$ES_AUTOHSCROLL))
$Button1 = GUICtrlCreateButton("Start", 40, 160, 91, 21, 0)
GUICtrlSetOnEvent(-1, "Button1Click")
GUISetState(@SW_SHOW)

Global $tt_path = "D:\Program Files\teraterm\ttermpro.exe"          ;path to your TeraTerm executable   
Global $tterm_log = "D:\Program Files\teraterm\teraterm.log"        ;path to your log
Global $remote_sw = _GUICtrlIpAddress_Get($IPAddress1)
Global $userName, $password
Global $tt_hwnd
#EndRegion ### END Koda GUI section ###

While 1
    Sleep(100)
WEnd

Func Button1Click()
    $userName = GUICtrlRead($UName)         ;read username
    $password = GUICtrlRead($pwd)           ;read password
    While WinExists ("Tera Term")           ;kill other TeraTerm if they exist
        WinKill ("Tera Term")
    WEnd
    $tterm = Run($tt_path&" "&$remote_sw&":9999 /L=teraterm.log")   ;run TeraTerm with Log      
    Sleep(1000)
    Do
        $tt_hwnd = ProcessGetHwnd($tterm)       ;get the handle of TeraTerm window
        Sleep(500)
    Until $tt_hwnd <> 0
    Sleep(1000)
    _SendTeraTerm($tt_hwnd, "")     ;send an empty line (this "empty line" will send an "ENTER") - I expect to get a login prompt
    _WaitPrompt("login:", 2000)     ;wait for login prompt
    _SendTeraTerm($tt_hwnd, $userName)  ;send login username
    _WaitPrompt("password:", 2000)      ;wait to be prompted for password
    _SendTeraTerm($tt_hwnd, $password, 1)   ;send password (option 1 because the password may contain special characters)
    _WaitPrompt(" # ", 2000)        ;in my case the current prompt contains "#"  - you have to change it to suit your needs
;here you will do whatever you need
;..................................
EndFunc

Func Form1Close()           ;Exit function
    Exit
EndFunc

Func ProcessGetHwnd($process)       ;get a process handle
    Local $n
    Local $list = WinList()
    For $n = 1 to $list[0][0]
        If WinGetProcess($list[$n][1]) = $process Then Return $list[$n][1]
    Next
    Return 0    
EndFunc
;================================================================================
;_SendTeraTerm($TThwnd, $command_tt) ............ send a command to Tera Term
    ;$TThwnd - Tera Term window handle
    ;$command_tt - the command to send to Tera Term
    ;$opt = 0 - option to send raw or control characters (default = 0 = control characters)
;This function will activate TT and attempt to send the command while is active - If NOT, it will display a tooltip 
;----------------------------------
Func _SendTeraTerm($TThwnd, $command_tt, $opt = 0)
    WinActivate ($TThwnd, "")
    While 1
        If WinActive ($TThwnd, "") Then
            ControlSend ($TThwnd, "", "",$command_tt&@CR, $opt)
            ToolTip("")
            ExitLoop
        Else
            ToolTip ( "Script PAUSED - Click Tera Term window to Resume", 20, 20, "Script PAUSED", 2,5)
        EndIf
    WEnd
    Sleep(300)
EndFunc 
;==============================================================================
;_WaitPrompt($prompt, $time_limit, $dlay = 0, $log) ... wait for a specific prompt to appear
    ;$prompt - what we expect to see (#, (y/n) ....)
    ;$time_limit - how long do we expect to take to get the prompt (miliseconds)
        ;@error = 1 if the time limit is exceeded
;--------------------------------------------
Func _WaitPrompt($prompt, $time_limit)
    Local $start = TimerInit()
    Do
        Sleep(400 )
        Local $aSplit = StringSplit(StringStripCR(FileRead($tterm_log)), @LF)
        Local $temp_line = $aSplit[$aSplit[0]]
        If TimerDiff ($start) > $time_limit Then
            SetError (1)
            ExitLoop
        EndIf
    Until StringInStr ($temp_line, $prompt)
EndFunc
;===============================================================================
;_ReadLogLastLine($log) ....................reads the last line in a log file
    ;$log = log file name
        ;@error = 1 if the file can't be opened
;-----------------------------
Func _ReadLogLastLine ($log, $b=0)          
    Local $hOpenFile

    $hOpenFile = FileOpen($log, 1)

    If $hOpenFile = -1 Then
        SetError(1)
    Else
        Local $aSplit = StringSplit(StringStripCR(FileRead($log)), @LF)
        Return $aSplit[$aSplit[0]-$b]
    EndIf
EndFunc
;===============================================================================

;===============================================================================
;_GetLogLastLineNumber ($log) ..............get the number of last line in a log file
    ;$log = log file name
        ;@error = 1 if the file can't be opened
;----------------------------------
Func _GetLogLastLineNumber ($log)           
    Local $hOpenFile

    $hOpenFile = FileOpen($log, 1)

    If $hOpenFile = -1 Then
        SetError(1)
    Else
        Local $aSplit = StringSplit(StringStripCR(FileRead($log)), @LF)
        Return $aSplit[0]
    EndIf
EndFunc
;===============================================================================

You have in this example everything you need to run whatever commands through TeraTerm. You will have to adapt it to your needs.

One important thing: you have to open TeraTerm - Click File->Log and set your log path and name before running my script. Also IMPORTANT - be sure that the checkbox "Append" is unchecked, that way you will start with a fresh log every time. If you forget to uncheck that the script won't fail but ... the file will grow and the script will need more and more time to find the info in the log - if the log is growing big the script will be slowed down alot. Don't forget about that!

This being said - good luck.

Edited by enaiman

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Link to comment
Share on other sites

With the huge help of enaiman's sample, I have everything working using Tera Term. I'm going to try it again using Telnet and maybe even hyper-terminal to see if they will work for my situation. Thank you all for your responses and help. I really do appreciate it.

Dave

Link to comment
Share on other sites

enaiman, you are rigth. :( but .....

there is also a solution for telnet: Instead of sending {ENTER} at end of the telnet command send {ENTER 2}

The second ENTER resilts in an additional NULL command and then the previous prompt is shown.

OK, it's a circumvention, but it works. :)

Edit: Typo

Fair enough :P

... But (again a "but") what if the prompt is a question like: "Are you sure you want to upgrade the bootrom? (y/n)" -> you won't be able to see such a prompt using Telnet (speaking from my work with switches where such questions appeared alot whenever I wanted to save configuration, upgrade firmware, bootrom ...)

Anyway, yours is a good workaround :idea:

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Link to comment
Share on other sites

Damnit,

I've fallen into a major glitch. I am using the "windows telnet method", but I want the telnet window hidden. Alas, when I do that, my script doesn't work.

I unhide the window and run it again, only to find that telnet can't produce a log. It says: "Failed to create log file."

After that, the only way I can make the script run is to change the directory where I store the log.

Even then, if I hide the telnet window again, I face the same issue...

I guess it has something to do with the window state. Maybe a hidden window cannot create files on the local disk?

Any ideas anyone?

Link to comment
Share on other sites

Hubertus, thanks for your time.

I'm afraid this is not the case. I compiled my script and ran it on a different PC. It 'crashed' first time out.

I use:

If FileExists($telnet_log) = True Then
    FileDelete ($telnet_log)                                    ; delete existing telnet log to be sure
EndIf
Sleep (500)
$Telnet = @ComSpec & " /k " & 'telnet -f "' & $telnet_log & '" ' & $server_ip
$pid = Run($Telnet, "", @SW_HIDE)
If @error Then Exit MsgBox(0, "Error PID", $pid)

I dont' think I'm doing sth wrong here.

If the reason is an open log file, why does this only happen when the terminal window is hidden?

Link to comment
Share on other sites

OK, trying your code, indeed, I get no error message. I am thinking that probably (as I mentioned), I am opening the log file somewhere in order to read it and then I forget to close it at the end of a conditional statement or something. It isn't obvious though.

I can give some excerpts of the code. The rest is not relevant to the problem and would be a pain to read due to its length. The part of the code that runs the telnet is:

Func _hps_login($smsc_ip, $telnet_log, $hps_userlogin, $hps_passlogin)                                 ; function that uses a remote session to login to an SMSC
    
    If FileExists($telnet_log) = True Then
        FileDelete ($telnet_log)                                                                             ; delete existing telnet log to be sure
    EndIf
    Sleep (500)
    $Telnet = @ComSpec & " /k " & 'telnet -f "' & $telnet_log & '" ' & $smsc_ip
    $pid = Run($Telnet, "", @SW_HIDE)
    If @error Then Exit MsgBox(0, "Error PID", $pid)
    
    WinWaitActive('Telnet ' & $smsc_ip)
    ControlSend('Telnet ' & $smsc_ip, "", "", $hps_userlogin & '{ENTER}')
    Sleep(1000)
    ControlSend('Telnet ' & $smsc_ip, "", "", $hps_passlogin & '{ENTER}')
    Sleep(1000)
    ControlSend('Telnet ' & $smsc_ip, "", "", '{ENTER}')
    Sleep(4000)
    ControlSend('Telnet ' & $smsc_ip, "", "", '{ENTER}')
        
EndFunc

Then this:

Func _session($hps_name, $smsc_ip, $telnet_log, $filecount, $hps_user, $hps_pass)                        ; function that takes care of the remote sessions
                                                                                                         ; function arguments:
                                                                                                             ; $hps_name = SMSC id & Server Name
                                                                                                             ; $smsc_ip = IP of SMSC server
                                                                                                             ; $telnet_log = path for telnet session log
                                                                                                             ; $filecount = number of audit files that have to be created by the ISFM procedure for the specific SMSC
                                                                                                             ; $hps_user = username for server
                                                                                                             ; $hps_pass = password for server
                                                                                                              
    $login_turn = 0                                                                                      ; variables used in order to perform login only ONCE within the 'Do' loop
    $commands_turn = 0
    
    Do                                                                                                   ; loop that logins to the SMSC, issues oommands and monitors the telnet log
        
        If $login_turn = 0 Then                                                                          ; conditional used in order to perform login only ONCE within the 'Do' loop
            
            _append_log(": Logging in to " & $hps_name & " " & $smsc_ip & " as " & $hps_user & " user from IP " & @IPAddress1 & "."); append message to log
            _hps_login($smsc_ip, $telnet_log, $hps_user, $hps_pass)                                          ; call login function
            
            $hps_log = FileOpen($telnet_log, 0)                                                          ; open telnet session log for reading
            $hps_log_read = FileRead($hps_log)                                                         ; store the contents of the telnet log
            _GUICtrlEdit_AppendText($EditBx_terminal, $hps_log_read)                                             ; load the contents of the telnet log to the Terminal EditBox

            If $hps_log = -1 Then                                                                        ; check if file open for reading OK and exit with an error message if this is NOT the case
                Beep(500, 100)
                MsgBox(48, "Error", "Please check that file " & $telnet_log & " exists.")
                ControlSend('Telnet ' & $smsc_ip, '', '', "logout" & '{ENTER}')
                WinClose ('Telnet ' & $smsc_ip)
                Exit
            EndIf

            If StringInStr($hps_log_read, $hps_name & "->") = True Then                                    ; conditional that checks if login was successful
                _append_log(": Login successful.")                                                         ; append message of success to log if login was performed successfully
                $login_turn = 1                                                                          ; make sure login is not performed again
            Else
                MsgBox(48, "Error", "Problem logging in to " & $hps_name & ".")
                WinClose ('Telnet ' & $smsc_ip)                                                          ; close telnet window and exit in case of failed login
                Beep(500, 100)
                Exit
            EndIf               
            
        EndIf
            
        Sleep(200)
        $f1 = _FileCountLines($telnet_log)                                                               ; store the line count of the telnet log
        $f2 = _GUICtrlEdit_GetLineCount ($EditBx_terminal)                                                       ; store the line count of the Terminal EditBox
        
        If $f1 <> $f2 Then                                                                               ; check if there is new data on the telnet log by comparing the linecount
            $hps_log_read = FileRead($hps_log)                                                         ; if the line counts differ, then store the extra contents of the telnet log
            _GUICtrlEdit_AppendText($EditBx_terminal, $hps_log_read)                                       ; and append them to the Terminal EditBox
        EndIf
    
        If $commands_turn = 0 Then                                                                       ; issue ISFM procedure commands by calling the relevant function
            _append_log(": Running ISFM file creation script on " & $hps_name & "...")                   ; append message of success to log if login was performed successfully
            _isfm_commands($smsc_ip, $hps_pass)
            $commands_turn = 1
        EndIf
        
    Until StringInStr($hps_log_read, "Total of " & $filecount & " files") = True                         ; end loop when files are created successfully (relevant string is found in PuTTY log)

EndFunc

Hubertus, thanks for your help so far in trying to figure this out.

Link to comment
Share on other sites

Nope, it's not opening/closing the file that's causing the problem.

For some reason telnet cannot create the file (regardless of path), when I have the command window hidden.

If I start with a minimized or restored window, the process takes place normally.

Weird...

Link to comment
Share on other sites

No luck with these two tips either.

BUT! I think I'm closing in on the culprit.

The problem is with WinWaitActive. If I comment it out, it works (most of the times). Does it ring any bells?

Edit: OK, it's a variable problem after all. The variable I am passing to telnet as log path is being used by the function that calls it, and this poses a problem for some reason. Please don't bother with this anymore, I'll figure it out eventually.

Paris

Edited by sonofalion
Link to comment
Share on other sites

  • 3 months later...

Damnit,

I've fallen into a major glitch. I am using the "windows telnet method", but I want the telnet window hidden. Alas, when I do that, my script doesn't work.

I unhide the window and run it again, only to find that telnet can't produce a log. It says: "Failed to create log file."

After that, the only way I can make the script run is to change the directory where I store the log.

Even then, if I hide the telnet window again, I face the same issue...

I guess it has something to do with the window state. Maybe a hidden window cannot create files on the local disk?

Any ideas anyone?

i was having a similar problem and overcome this by using the following script: its much like the one above but with a few changes. and i do believe it works to the best of the ability of telnet. its designed for a front end for a client on a telnet chat server.

#include <GUIConstants.au3>
#include <GuiEdit.au3>

$DefaultHost = "127.0.0.1"
$DefaultPort = "23"
$configfile = "clientsettings.ini"
If Not FileExists($configfile) Then
    IniWrite($configfile, "ConnectTo", "Host", $DefaultHost)
    IniWrite($configfile, "ConnectTo", "Port", $DefaultPort)
EndIf
$HostI = IniRead($configfile, "ConnectTo", "Host", $DefaultHost)
$PortI = IniRead($configfile, "ConnectTo", "Port", $DefaultPort)
$Telnetserver = $HostI & " " & $PortI
$Wintitle = "Telnet chat client"
$Filename = "telnetclient.log"
$Cmd = @ComSpec & " /k " & 'telnet -f "' & $Filename & '" ' & $Telnetserver
GUICreate($Wintitle)
$Input = GUICtrlCreateInput("", 10, 320, 300, 20)
$Send = GUICtrlCreateButton("Send", 320, 320)
$Edit = GUICtrlCreateEdit("", 10, 10, 380, 300, $WS_VSCROLL+$ES_AUTOVSCROLL,$WS_EX_TRANSPARENT)
$telnetwintitle = "Telnet " & $HostI
$sent = 0

Func terminate()
    FileDelete($Filename)
    WinClose($telnetwintitle)
    Exit
EndFunc

Func _send_txt($a)
    GUICtrlSetData($Input, "")
    ControlSend($telnetwintitle, "", "", $a & "{ENTER}")
EndFunc

$pid = Run($Cmd, "", @SW_HIDE)
If @error Then Exit MsgBox(0, "Error PID", $pid)

GUISetState()
While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then terminate()
    If $msg = $Send Then _send_txt(GUICtrlRead($Input))
    If $msg = $Input Then _send_txt(GUICtrlRead($Input))
    If GUICtrlRead($Edit) <> FileRead($Filename) Then
        GUICtrlSetData($Edit, FileRead($Filename))
        _GUICtrlEdit_Scroll($Edit, $SB_SCROLLCARET)
    EndIf
WEnd

Quoted from Micro$ofts development team:Gentlemen, I say rather than fix the 'bugs', we change the documentation and call them 'features'.

Link to comment
Share on other sites

  • 7 months later...

OK, I know it's been a while, but I just saw this posting....

i was having a similar problem and overcome this by using the following script: its much like the one above but with a few changes. and i do believe it works to the best of the ability of telnet. its designed for a front end for a client on a telnet chat server.

Timmo - your script works great!! But it's missing a few include.

; add these below other includes
#include <EditConstants.au3>
#include <WindowsConstants.au3>
#include <ScrollBarConstants.au3>

Thanks!

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...