0

I am looking for a way to help me ssh open a binary client in raspberry pi and send a few commands in that client. I try 2 ways:

  SshClient sshclient = new SshClient(HostAddress, "pi", "raspberry");

  sshclient.Connect();

  using (SshCommand sc = sshclient.CreateCommand(
"rm /tmp/liblog.txt; 
 cd /home/pi; 
 sudo ./myClient -s ffdd::aabb:3; 
 setdefault; 
 exit"))
            {               
                var asyncExecute = sc.BeginExecute();
                sc.OutputStream.CopyTo(Console.OpenStandardOutput());

                Delay(60000);
                sc.EndExecute(asyncExecute);
            }
  sshclient.Disconnect();
  sshclient.Dispose();

As you can see, I have 5 commands in here, the ssh process works ok before I run myClient. But when the client is running, the next command doesn't execute anymore. myClient is running but it doesn't do further actions. I am also trying this way and get the same result:

public void runMyClient(string HostAddress)
        {
            string command = " /nointeractiveinput /command \"open " + HostProtocol + "://" + HostLogin + "@" + HostAddress +
                "/\" \"call cd /home/pi/\"" +
                " \"call ./myClient -s ffdd::aabb:3"" +
                " \"call setdefault\"";

            Console.WriteLine(command);

            System.Diagnostics.Process cmd = new System.Diagnostics.Process();
            cmd.StartInfo.FileName = "\"C:\\Program Files (x86)\\WinSCP\\WinSCP.com\"";
            cmd.StartInfo.RedirectStandardInput = true;
            cmd.StartInfo.RedirectStandardOutput = true;
            cmd.StartInfo.CreateNoWindow = true;
            cmd.StartInfo.UseShellExecute = false;
            cmd.StartInfo.Arguments = command;

            cmd.Start();
            Console.WriteLine(cmd.StandardOutput.ReadToEnd());
            cmd.WaitForExit();
            cmd.StandardInput.Close();
            cmd.Close();
        }

Thanks for the help.

  • Are you getting to the line after WaitForExit? Add a break point and see if you get to the break point. I think you are never getting an exit. – jdweng Feb 06 '20 at 10:25
  • @jdweng yes, you are correct. sc.EndExecute(asyncExecute); never ended, I guess it is because since when it running the client, ssh couldn't do anything. – suppermanzz Feb 06 '20 at 10:30
  • It is the way cmd.exe behaves. The application is probably keeping the command window open so you do not get an exit until the window closes. When the process finish it probably send a message on standard output (process standard input). So if you connect an Asynchronous stream to the ReddirectStandard input you can determine when the process finishes when you get a prompt or message. – jdweng Feb 06 '20 at 10:34
  • @jdweng thanks for the explanation. The problem is I need to execute a few commands using that application. Currently, the ssh can only help me to open and run that application in RPi, but I am looking for a way to do the rest of the process. I thought ssh can also do send commands to that application. – suppermanzz Feb 06 '20 at 10:39
  • See [Providing subcommands to a command (sudo/su) executed with SSH.NET SshClient.CreateShellStream](https://stackoverflow.com/q/54194139/850848). – Martin Prikryl Feb 06 '20 at 13:07
  • @MartinPrikryl thanks Martin, I found the same solutions and put them below already : ) – suppermanzz Feb 06 '20 at 13:56

1 Answers1

0

I just found a way to solve my question : ) For this situation, just using CreateShellStream and StreamReader/StreamWriter to achieve this purpose.

            SshClient sshclient = new SshClient(HostAddress, "pi", "raspberry");
            sshclient.Connect(); 

            string default_set_status_done = "DEFAULT_SET_DONE";
            string default_set_status_failed = "DEFAULT_SET_FAIL";
            var s = sshclient.CreateShellStream("Commands", 240, 200, 132, 80, 1024);

            var reader = new StreamReader(s);
            var writer = new StreamWriter(s);
            writer.AutoFlush = true;

            // Do the read command
            writer.WriteLine("rm /tmp/liblog.txt");
            Thread.Sleep(200);
            writer.WriteLine("cd /home/pi/");
            Thread.Sleep(200);
            writer.WriteLine("sudo ./myClient -s ffdd::aabb:3");
            Thread.Sleep(200);
            writer.WriteLine("setdefault");
            Thread.Sleep(30000);
            writer.WriteLine("exit");
            Thread.Sleep(10000);

            string l = "";
            while ((l = reader.ReadLine()) != null)
            {
                Console.WriteLine(l);
                if (l.Contains(default_set_status_done))
                {
                    ReportService.LogOk("set default completed.");
                }
                else if (l.Contains(default_set_status_failed))
                {
                    Inconclusive("set default failed!");
                }                
            }

This works for me. You can find more reference in here: https://csharp.hotexamples.com/examples/Renci.SshNet/SshClient/CreateShellStream/php-sshclient-createshellstream-method-examples.html