Plink is a command-line version of PuTTY, a Windows SSH client program. I am trying to get the output from plink to display in a textbox within a VB form. I can get it to work but I must hit the ENTER key twice before it shows anything, everytime. So I end up with repeated commands thrown at plink. Anyone know why I'm seeing this?

Imports System.Text
Imports System.IO

Public Class Form1
    ' Define static variables shared by class methods.
    Private Shared shellOutput As StringBuilder = Nothing
    Private Shared numOutputLines As Integer = 0
    Private Shared stdIN As StreamWriter
    Private Shared p As New Process

    Private Shared Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
        stdIN.WriteLine(Form1.txtSend.Text.ToString)
        'stdIN.Flush()
        Form1.txtReceive.Text = shellOutput.ToString
    End Sub

    Private Sub btnLogin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLogin.Click
        Dim p_info As New ProcessStartInfo
        p_info.FileName = "C:\plink.exe"
        p_info.Arguments = " -l username -pw password host"
        p_info.UseShellExecute = False
        p_info.CreateNoWindow = True
        p_info.RedirectStandardOutput = True
        p_info.RedirectStandardInput = True

        ' Set our event handler to asynchronously read the shell output.
        AddHandler p.OutputDataReceived, AddressOf dirOutputHandler
        shellOutput = New StringBuilder
        p.StartInfo = p_info
        p.Start()
        stdIN = p.StandardInput
        p.BeginOutputReadLine()
        System.Threading.Thread.Sleep(5000)
        txtReceive.Text = shellOutput.ToString
    End Sub

    Private Shared Sub dirOutputHandler(ByVal sendingProcess As Object, ByVal outLine As DataReceivedEventArgs)
        ' Collect the sort command output.
        If Not String.IsNullOrEmpty(outLine.Data) Then
            numOutputLines += 1

            ' Add the text to the collected output.
            shellOutput.Append(Environment.NewLine + outLine.Data)
        End If
    End Sub
End Class

Dani AI

Generated

Most likely this is a buffering/timing problem rather than a plink bug. The fact that stepping through in the debugger "fixes" it is a classic sign: the first WriteLine call is getting stuck in a StreamWriter buffer (or the remote side is writing prompts to stderr), so nothing appears until a later action forces the buffer to flush.

Practical fixes to try (ordered by simplest -> more robust):

  • Immediately after you grab the process input writer enable autoflush or call Flush after each WriteLine. Example:

    stdIN = p.StandardInput
    stdIN.AutoFlush = True

    or call stdIN.Flush() right after WriteLine.

  • Capture stderr too; plink (and many console tools) may send prompts/warnings to the error stream. Enable RedirectStandardError and start reading it (BeginErrorReadLine).

  • Stop using Thread.Sleep for timing. Make the UI update when data actually arrives instead of immediately reading your StringBuilder. Update the textbox from the Output/Error handlers using the form thread (BeginInvoke/Invoke) to avoid race and cross-thread issues. For example, switch to instance handlers and do something like:

    If Not String.IsNullOrEmpty(e.Data) Then
        Me.BeginInvoke(Sub() txtReceive.AppendText(e.Data & Environment.NewLine))
    End If
  • Avoid duplicate commands: the WriteLine/flush pattern will prevent the "first ENTER does nothing" symptom. For extra reliability implement a simple command queue that only sends the next command after you detect the remote prompt in the output (or after a confirmed response).

Other notes: make handlers instance-level (not Shared) so you can safely call BeginInvoke, and protect any shared buffers (StringBuilder) with a lock if you keep them. If issues persist, try forcing a pty allocation with plink's -t option and test with a simple echo hello to isolate whether output goes to stdout or stderr.

As observed, the debugger timing hid the race — the above changes address that directly.

I was stepping through the code in a debugger and found that when I do it that way, I dont have to hit ENTER twice. For some reason, it works properly in the debugger. I think this may be a timing issue.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.