Home All Groups Group Topic Archive Search About

Using PLink interactively as a Telnet process with VB.Net 2003

Author
3 Apr 2006 3:10 PM
Al
I'm currently attempting to use PLink (the console component of PUTTY - see
http://www.chiark.greenend.org.uk/~sgtatham/putty/) as a Telnet component as
I may in future need to change to using SSH and this seems an ideal solution.
I'm running it as a process and re-directing the standardinput/output/error

However, despite working through all the different variations of code I can
either think of or find I am unable to achieve true interactivity with the
program (which would be nice). I can happily pass commands to the program,
but once it has connected to the Telnet destination (i.e. Once I have passed
the password), I do not get any output returned to standardoutput until PLink
exits, at which point I get it all. I have tried reading the
standardoutput/error on different threads to see if they were blocking the
processing, but this did not seem to be the case, so I dropped back to the
simpler more hackable code you see below.

I have attached the main block below, it's not very neat due to being
reworked multiple times and may now contain some redundant bits so apologies
in advance. Hopefully however it may provide a basis for someone to point out
what I need to change to get this thing working.

    Friend Shared TelnetProcess As System.diagnostics.Process = New
System.diagnostics.Process
    Friend Shared TelnetStage As Integer = 0
    Friend Shared TelnetBuffer As String = ""
    Friend Shared TelnetBufferFull As String = ""
    Friend Shared TelnetIn As StreamWriter
    Friend Shared TelnetOut As StreamReader
    Friend Shared TelnetErr As StreamReader
    Friend WithEvents tmrProcessAIX As System.Timers.Timer = New
System.Timers.Timer
    Friend WithEvents tmrProcessSwitch As System.Timers.Timer = New
System.Timers.Timer
    Friend WithEvents objStdOutRead As clsStdOutRead = New clsStdOutRead
    Friend WithEvents objStdErrRead As clsStdErrRead = New clsStdErrRead
    Friend thrdProcessStdOutRead As Thread = New Thread(AddressOf
objStdOutRead.StdOutRead)
    Friend thrdProcessStdErrRead As Thread = New Thread(AddressOf
objStdErrRead.StdErrRead)

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

        TextBox1.Text = ""

        TelnetStage = 0
        TelnetBuffer = ""
        TelnetBufferFull = ""

        TelnetProcess.StartInfo.FileName = Application.StartupPath &
"\tools\" & "plink.exe"
        TelnetProcess.StartInfo.Arguments = " -telnet 192.168.1.6 -l myid"
        TelnetProcess.StartInfo.UseShellExecute = False
        TelnetProcess.StartInfo.CreateNoWindow = True
        TelnetProcess.StartInfo.RedirectStandardInput = True
        TelnetProcess.StartInfo.RedirectStandardOutput = True
        'TelnetProcess.StartInfo.RedirectStandardError = True
        TelnetProcess.Start()
        TelnetIn = TelnetProcess.StandardInput
        TelnetOut = TelnetProcess.StandardOutput
        TelnetErr = TelnetProcess.StandardOutput
        TelnetProcess.StandardInput.AutoFlush = True
        tmrProcess.Interval = 1000
        tmrProcess.Enabled = True

    End Sub

    Sub tmrProcess_Elapsed(ByVal sender As Object, ByVal e As
System.Timers.ElapsedEventArgs) Handles tmrProcessAIX.Elapsed

        Dim sOutBuffer As String = ""
        Dim x As String
        Dim iChar As Integer

        Try
            Select Case TelnetStage
                Case 0
                    tmrProcessAIX.Enabled = False
                    Do While TelnetProcess.StandardOutput.Peek() >= 0
                        iChar = TelnetProcess.StandardOutput.Read()
                        TelnetBuffer = TelnetBuffer & (Convert.ToChar(iChar))
                        Console.WriteLine("TB >" & TelnetBuffer.ToString())
                    Loop
                    If (InStr(TelnetBuffer, "Password:") > 0) Then
                        TelnetProcess.StandardInput.Write("password" & vbCrLf)
                        TelnetBufferFull = TelnetBufferFull & TelnetBuffer &
"xxxxxxxx" & System.Environment.NewLine
                        TelnetBuffer = ""
                        TelnetStage = 1
                    End If
                    tmrProcessAIX.Enabled = True
                Case 1
                    tmrProcessAIX.Enabled = False
                    Do While TelnetProcess.StandardOutput.Peek() >= 0
                        iChar = TelnetProcess.StandardOutput.Read()
                        TelnetBuffer = TelnetBuffer & (Convert.ToChar(iChar))
                        Console.WriteLine("TB >" & TelnetBuffer.ToString())
                    Loop
                    TelnetProcess.StandardInput.WriteLine("command" & vbCrLf)
                    TelnetBufferFull = TelnetBufferFull & TelnetBuffer
                    TelnetBuffer = ""
                    TelnetStage = 98
                    tmrProcessAIX.Enabled = True

                Case 98
                    tmrProcessAIX.Enabled = False
                    Do While TelnetProcess.StandardOutput.Peek() >= 0
                        iChar = TelnetProcess.StandardOutput.Read()
                        TelnetBuffer = TelnetBuffer & (Convert.ToChar(iChar))
                        Console.WriteLine("TB >" & TelnetBuffer.ToString())
                    Loop
                    TelnetProcess.StandardInput.WriteLine("exit" & vbCrLf)
                    TelnetProcess.StandardInput.WriteLine("exit" & vbCrLf)
                    TelnetBufferFull = TelnetBufferFull & TelnetBuffer
                    TelnetBuffer = ""
                    TelnetStage = 99
                    Console.WriteLine("TBF>" & TelnetBufferFull)
                    tmrProcessAIX.Enabled = True
                Case 99
                    tmrProcessAIX.Enabled = False
                    Do While TelnetProcess.StandardOutput.Peek() >= 0
                        iChar = TelnetProcess.StandardOutput.Read()
                        TelnetBuffer = TelnetBuffer & (Convert.ToChar(iChar))
                        Console.WriteLine("TB >" & TelnetBuffer.ToString())
                    Loop
                    TelnetBufferFull = TelnetBufferFull & TelnetBuffer
                    x = TelnetBufferFull &
TelnetProcess.StandardOutput.ReadToEnd
                    'MsgBox(x)
                    TextBox1.Text = x
                    TelnetProcess.Kill()
            End Select

        Catch ioe As InvalidOperationException
        Catch ex As Exception
            MsgBox(ex.ToString)
        Finally
        End Try

    End Sub


--
Al
Systems Type

Author
4 Apr 2006 1:07 PM
vglass
Consider using Telnet Factory for .NET and SSH Factory for .NET
together to obtain both telnet and ssh scripting functionality:

http://www.jscape.com/telnetfactorydotnet/

http://www.jscape.com/sshfactorydotnet/


Al wrote:
Show quoteHide quote
> I'm currently attempting to use PLink (the console component of PUTTY - see
> http://www.chiark.greenend.org.uk/~sgtatham/putty/) as a Telnet component as
> I may in future need to change to using SSH and this seems an ideal solution.
> I'm running it as a process and re-directing the standardinput/output/error
>
> However, despite working through all the different variations of code I can
> either think of or find I am unable to achieve true interactivity with the
> program (which would be nice). I can happily pass commands to the program,
> but once it has connected to the Telnet destination (i.e. Once I have passed
> the password), I do not get any output returned to standardoutput until PLink
> exits, at which point I get it all. I have tried reading the
> standardoutput/error on different threads to see if they were blocking the
> processing, but this did not seem to be the case, so I dropped back to the
> simpler more hackable code you see below.
>
> I have attached the main block below, it's not very neat due to being
> reworked multiple times and may now contain some redundant bits so apologies
> in advance. Hopefully however it may provide a basis for someone to point out
> what I need to change to get this thing working.
>
>     Friend Shared TelnetProcess As System.diagnostics.Process = New
> System.diagnostics.Process
>     Friend Shared TelnetStage As Integer = 0
>     Friend Shared TelnetBuffer As String = ""
>     Friend Shared TelnetBufferFull As String = ""
>     Friend Shared TelnetIn As StreamWriter
>     Friend Shared TelnetOut As StreamReader
>     Friend Shared TelnetErr As StreamReader
>     Friend WithEvents tmrProcessAIX As System.Timers.Timer = New
> System.Timers.Timer
>     Friend WithEvents tmrProcessSwitch As System.Timers.Timer = New
> System.Timers.Timer
>     Friend WithEvents objStdOutRead As clsStdOutRead = New clsStdOutRead
>     Friend WithEvents objStdErrRead As clsStdErrRead = New clsStdErrRead
>     Friend thrdProcessStdOutRead As Thread = New Thread(AddressOf
> objStdOutRead.StdOutRead)
>     Friend thrdProcessStdErrRead As Thread = New Thread(AddressOf
> objStdErrRead.StdErrRead)
>
>     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
> System.EventArgs) Handles Button1.Click
>
>         TextBox1.Text = ""
>
>         TelnetStage = 0
>         TelnetBuffer = ""
>         TelnetBufferFull = ""
>
>         TelnetProcess.StartInfo.FileName = Application.StartupPath &
> "\tools\" & "plink.exe"
>         TelnetProcess.StartInfo.Arguments = " -telnet 192.168.1.6 -l myid"
>         TelnetProcess.StartInfo.UseShellExecute = False
>         TelnetProcess.StartInfo.CreateNoWindow = True
>         TelnetProcess.StartInfo.RedirectStandardInput = True
>         TelnetProcess.StartInfo.RedirectStandardOutput = True
>         'TelnetProcess.StartInfo.RedirectStandardError = True
>         TelnetProcess.Start()
>         TelnetIn = TelnetProcess.StandardInput
>         TelnetOut = TelnetProcess.StandardOutput
>         TelnetErr = TelnetProcess.StandardOutput
>         TelnetProcess.StandardInput.AutoFlush = True
>         tmrProcess.Interval = 1000
>         tmrProcess.Enabled = True
>
>     End Sub
>
>     Sub tmrProcess_Elapsed(ByVal sender As Object, ByVal e As
> System.Timers.ElapsedEventArgs) Handles tmrProcessAIX.Elapsed
>
>         Dim sOutBuffer As String = ""
>         Dim x As String
>         Dim iChar As Integer
>
>         Try
>             Select Case TelnetStage
>                 Case 0
>                     tmrProcessAIX.Enabled = False
>                     Do While TelnetProcess.StandardOutput.Peek() >= 0
>                         iChar = TelnetProcess.StandardOutput.Read()
>                         TelnetBuffer = TelnetBuffer & (Convert.ToChar(iChar))
>                         Console.WriteLine("TB >" & TelnetBuffer.ToString())
>                     Loop
>                     If (InStr(TelnetBuffer, "Password:") > 0) Then
>                         TelnetProcess.StandardInput.Write("password" & vbCrLf)
>                         TelnetBufferFull = TelnetBufferFull & TelnetBuffer &
> "xxxxxxxx" & System.Environment.NewLine
>                         TelnetBuffer = ""
>                         TelnetStage = 1
>                     End If
>                     tmrProcessAIX.Enabled = True
>                 Case 1
>                     tmrProcessAIX.Enabled = False
>                     Do While TelnetProcess.StandardOutput.Peek() >= 0
>                         iChar = TelnetProcess.StandardOutput.Read()
>                         TelnetBuffer = TelnetBuffer & (Convert.ToChar(iChar))
>                         Console.WriteLine("TB >" & TelnetBuffer.ToString())
>                     Loop
>                     TelnetProcess.StandardInput.WriteLine("command" & vbCrLf)
>                     TelnetBufferFull = TelnetBufferFull & TelnetBuffer
>                     TelnetBuffer = ""
>                     TelnetStage = 98
>                     tmrProcessAIX.Enabled = True
>
>                 Case 98
>                     tmrProcessAIX.Enabled = False
>                     Do While TelnetProcess.StandardOutput.Peek() >= 0
>                         iChar = TelnetProcess.StandardOutput.Read()
>                         TelnetBuffer = TelnetBuffer & (Convert.ToChar(iChar))
>                         Console.WriteLine("TB >" & TelnetBuffer.ToString())
>                     Loop
>                     TelnetProcess.StandardInput.WriteLine("exit" & vbCrLf)
>                     TelnetProcess.StandardInput.WriteLine("exit" & vbCrLf)
>                     TelnetBufferFull = TelnetBufferFull & TelnetBuffer
>                     TelnetBuffer = ""
>                     TelnetStage = 99
>                     Console.WriteLine("TBF>" & TelnetBufferFull)
>                     tmrProcessAIX.Enabled = True
>                 Case 99
>                     tmrProcessAIX.Enabled = False
>                     Do While TelnetProcess.StandardOutput.Peek() >= 0
>                         iChar = TelnetProcess.StandardOutput.Read()
>                         TelnetBuffer = TelnetBuffer & (Convert.ToChar(iChar))
>                         Console.WriteLine("TB >" & TelnetBuffer.ToString())
>                     Loop
>                     TelnetBufferFull = TelnetBufferFull & TelnetBuffer
>                     x = TelnetBufferFull &
> TelnetProcess.StandardOutput.ReadToEnd
>                     'MsgBox(x)
>                     TextBox1.Text = x
>                     TelnetProcess.Kill()
>             End Select
>
>         Catch ioe As InvalidOperationException
>         Catch ex As Exception
>             MsgBox(ex.ToString)
>         Finally
>         End Try
>
>     End Sub
>
>
> --
> Al
> Systems Type
Author
5 Apr 2006 6:42 AM
Al
Two points on that :

1. I would prefer not to use a commercial addin component as I have no
budget available for one.

2. Whilst in this instance I'm using PLink, it is likely that I will have
other external console/command-line programs to wrap and therefore I would
like to get the procedure sorted out properly now.

Al
Systems Type


"vgl***@jscape.com" wrote:

> Consider using Telnet Factory for .NET and SSH Factory for .NET
> together to obtain both telnet and ssh scripting functionality:
>
<snip>