This project is read-only.

Is it possible to pass a command as a WriteLine via the SSH client similar to the SshShell class in Tamir.SharpSSH?

Jan 28, 2012 at 6:16 PM

Hi,

I have only just started playing with the idea of using an SSH client as part of a VB.NET application to remote control certain devices.

Originally, I have been using the Tamir.SharpSSH client and was able to connect to the remote device and issue a command as if it were manually typed into an SSH client using the following basic code.

Shell = New SshShell(Info.Host, Info.User) 
Shell.Password = Info.Pass 
Shell.Connect() 

Command As String = "command to run" 
Shell.WriteLine(Command & vbCr) 

Shell.Close()

I did also try the SshExec object from Tamir.SharpSSH, but when I tried to run a remote command, the application just hung.

I then came across this project that update and re-write the original code of Tamir.SharpSSH, so i thought I'd give it a whirl. Obviously, there are a lot of differences and as a non-expect programmer I am trying to get to grips with what is offered here. I have used to follow code (from another user example) to try and execute a command via the SSH session:

        Try
            Shell = New SshClient(Info.Host, Info.User, Info.Pass)
            Shell.Connect()

            cmd = Shell.CreateCommand("command to run")
            cmd.CommandTimeout = TimeSpan.FromSeconds(10)

            result = cmd.Execute
            result2 = cmd.Error
            txtConsoleOutput.Text = cmd.ExitStatus

            If String.IsNullOrEmpty(result2) Then
                txtConsoleOutput.Text = result2
            End If

            txtConsoleOutput.Text = result

        Catch ex As Exception
            MsgBox(ex.Message)

        Finally
            Shell.Disconnect()
        End Try
However, exactly the same thing happens as when I tried to use the SshExec object from Tamir.SharpSSH, the remote command just times out, so throws an exception when the application tries to run "result = cmd.Execute"

Is there any way to get the functionality found in the SshShell.WriteLine method from Tamir, or am I simply doing something basically wrong?

 

Cheers,

Coordinator
Jan 29, 2012 at 1:50 AM

Hi,

 

To simulate WriteLine functionality from Tamir.SharpSSH library you need to use Shell functiolity, this is where you can read and write data into the shell.

When you do command execution, it executes singles command in the default shell and the exits, as soon as command ends.

 

Here some example on how to use shell:

using (var ssh = new SshClient(connectionInfo))
            {
                ssh.Connect();
                var input = new MemoryStream();  
                var sr = new StreamWriter(input);
                var output = Console.OpenStandardOutput();
                var shell = ssh.CreateShell(input, output, output, "xterm", 80, 24, 800, 600, "");
                shell.Stopped += delegate
                {
                    Console.WriteLine("\nDisconnected...");
                };
                shell.Start();
                sr.Write("su root");
                sr.Flush();
                Thread.Sleep(1000 * 1);
                sr.WriteLine("password");
                sr.Flush();
                Thread.Sleep(1000 * 100);
                shell.Stop();

here all output will go to the console but you can always replace it with your own stream if you want to capture it.

 

Hope it helps.

 

Thanks,

Oleg

Jan 30, 2012 at 7:18 PM

Thanks Oleg. I might be able to figure this out and convert it to VB (not sure over the += delegate bit).

As said, I'm no programmer, merely enthusisatic. Whilst I kinda of get what a stream is (as in stream of data), I haven't really dealt with them in my programming as yet, so have no real idea on how to use or manipulate them, so I like your comment "but you can always replace it with your own stream if you want to capture it" :).

I'll have a play and see what I can do, but I do like the simple implementation and use of SshShell in Tamir.SharpSSH.

Cheers

Feb 7, 2012 at 12:35 AM
Edited Feb 7, 2012 at 12:50 AM

Hi Oleg,

I have had a little play with your ideas but still can't get it to work. Most of the above converts relatively simply into VB.Net but I don't understand the sectionso I wouldn't know the first clue on how to convert it. Beyond my programming understanding at the moment I'm afraid

                shell.Stopped += delegate
                {
                    Console.WriteLine("\nDisconnected...");
                };

From what I have done, I can see that the client connects and the shall starts and certainly returns the system logon info to the Output window, however actually issuing a command as a WriteLine seems to do nothing. Below is the similar thing in VB (minus the code above) (apologies but the Code inset doesn't seem to be working.)

       Dim Input As MemoryStream = New MemoryStream()
        Dim SW As StreamWriter = New StreamWriter(Input)
        Dim Output = Console.OpenStandardOutput()

        ConnectionInfo = New PasswordConnectionInfo(Host, User, Pass)


            Using Client = New SshClient(ConnectionInfo)

                Client.Connect()
                Shell = Client.CreateShell(Input, Output, Output, "xterm", 80, 24, 800, 600, "")

                Shell.Start()
                SW.WriteLine("command to send")
                SW.Flush()

                SW.WriteLine("command to send")
                SW.Flush()

                Shell.Stop()

            End Using

I have tried a couple of permeations of sending the command lines but no joy. What does the section of code above that I don't understand and cant convert actually do?

Coordinator
Feb 7, 2012 at 2:27 PM

Hi,

 

I just tried it myself and it looks like this particular case does not work :(.

I guess I changed something overtime. One thing I forgot to mention I think is that you should finish all your commands with \r\n, since shell waiting for an Enter.

What still works is if you populate input stream before or if you use :

var input = Console.OpenStandardInput();

for input.

 

I dont know why when I use standard input it works, since its regular Stream, but I guess I am missing something.

 

I will have to get back to Shell implementation to improve it when I have some extra time then.

 

Oleg

Feb 7, 2012 at 5:08 PM
Edited Feb 7, 2012 at 5:35 PM
olegkap wrote:

One thing I forgot to mention I think is that you should finish all your commands with \r\n, since shell waiting for an Enter.


I did test using the "& vbCr" added to the end of the string, which made no difference. Not sure if this is the same as adding "\r\n" to the end of the command string I know vbCr workied with Tamir SSH

 

olegkap wrote:

What still works is if you populate input stream before or if you use :

var input = Console.OpenStandardInput();

for input.

 

I dont know why when I use standard input it works, since its regular Stream, but I guess I am missing something.

I will have to get back to Shell implementation to improve it when I have some extra time then.

Oleg

I am trying to pass per-assigned commands to the Shell rather than have the user enter them via the console - after all to do that we would simply use putty. Essentially this box exposes a custom set of commands that then allows operation of connected devices. Rather than ask the user to type in the command, an action will be assigned to a form event (i.e. button click) which will then send the command to the Shell. I therefor need to keep the connection and shell open and pass in new commands as required.When you say "populate input stream before or if you use" do you mean that 'input' need to be set with the command to action BEFORE I call

Shell = Client.CreateShell(Input, Output, Output, "xterm", 80, 24, 800, 600, "")

In which case does this mean I can only use one command for each time I create an instance of the Shell?

Feb 8, 2012 at 2:55 PM
Edited Feb 16, 2012 at 10:00 PM

Hi Oleg,

 

Well, I have tried many permutations using the Console.StandardInput assigned to "input". I have tried writing to the console prior to creating the shell (silly really but had to try), I've tried lot of different emulation characters ("\r\n, "CRLF", "/r/n" ... ) but still no joy. Output from the Shell is getting to the console as I'm getting system messages. However there is still an issue with the input

Although something like

Console.WriteLine("xcommand CameraPosition camera:1 pan:32000 tilt:-32000\n\r")

shows in VS Output Debug window, it's not actually doing anything in the Shell.

                SW.Write("xcommand CameraPosition camera:1 pan:32000 tilt:-32000\n\r")
                SW.Flush()
Feb 16, 2012 at 9:59 PM

Hi Oleg,

I don't suppose you have had any time to look at this? At the moment, utilising this SSH client is a non starter for me. Even if I could get the Console.OpenStandardInput() stream working so I could then write lines programtically to the Console to pass them to the SSH Server would be a step in the right direction, but even this doesn't work for me.

Many thanks

Coordinator
Feb 21, 2012 at 2:05 PM

Hi,

 

Sorry, it took a while.

Please take a look at new ShellStream class and see if it works for you.

I have a thread which is dedicated to that so please leave your feedback there.

 

Thanks,

Oleg

Mar 1, 2012 at 5:58 PM

Hi Oleg,

 

I have just managed to get round to testing the new class an I have got it to do what I'm after - to a degree - so many thanks. There is a glitch in the operation of the code (which is probably of my making, but I will post the result back in your other thread.

Many thanks for getting this working.

Chris