title: Sending input during command output with SSH.NET
body: <p>With PuTTY, I connect to an SSH server and then I execute a command that constantly output logs (multiple lines per second). During this process I can send some keystrokes which are commands, ie. putting <code>123</code> or <kbd>Esc</kbd> which stops the process. If I put a valid keystroke I can see it on output device, so I always know if keystroke was sent or not.</p>
  
  <p>I want to do it programmatically - connect to the SSH server, execute the main command and then send it some key strokes as commands while in the same time monitoring the logs where I can see the response to my commands.</p>
  
  <p>So I want to do it with SSH.NET - it's a neat SSH tool, it outputs reliably and it's nice to work with. However I have a problem - I can connect to this server, execute a command, but while it dumps the log I cannot send it any key stroke.</p>
  
  <p>Ways I've tried using <code>CreateShellStream</code>:</p>
  
  <ul>
  <li><code>shellStream.WriteLine('keystroke in ascii or just string')</code></li>
  <li><code>sshClient.CreateCommand('keystroke in ascii or just string')</code> and then <code>sshClient.Execute()</code>;</li>
  <li>using <code>StreamWriter(shellstream)</code> and writing to it</li>
  </ul>
  
  <p>I've tried ascii codes, UTF-16 codes, strings, nothing works unfortunately. </p>
  
  <p>The same thing done with Plink (PuTTY command-line tool) works just fine, but it's much messier and I would prefer to use SSH.NET. Do you know what is the difference between sending keystrokes with SSH.NET and Plink? Why does it work flawlessly with Plink? I've tried debugging it with Wireshark, unfortunately SSH makes it really difficult to do so.</p>
  
  <p>With Plink I'm using basically something like this:</p>
  
  <pre><code>ProcessStartInfo psi = new ProcessStartInfo("plink.exe", arguments);
  psi.RedirectStandardError = true;
  psi.RedirectStandardOutput = true;
  psi.RedirectStandardInput = true;
  psi.UseShellExecute = false;
  plink = Process.Start(psi);
  StreamWriter input = plink.StandardInput;
  StreamReader output = plink.StandardOutput;
  
  input.WriteLine("startCommand"); //Starts the process responsible for logs
  
  input.Write("950"); //It correctly sends the keystrokes
  
  // Some code regarding reading logs from output, some other commands sent to ssh server...
  
  Console.WriteLine("Exiting...");
  input.Write('\u001b');  //ESC in UTF16
  </code></pre>
  
  <p>I think that SSH.NET waits for the last command to end before sending anything else but I don't know how to change it.</p>
  
  <hr>
  
  <p>My tries using SSH.NET:</p>
  
  <pre><code>using (var client = new SshClient(host, user, new PrivateKeyFile(key)))
  {
      int timoutCounter = 0;
      do
      {
          timoutCounter++;
          try { client.Connect(); }
          catch (Exception e)
          {
              Console.WriteLine("Connection error: " + e.Message);
          }
      } while (!client.IsConnected);
  
      ShellStream stream = client.CreateShellStream("shell", 200, 24, 1920, 1080, 4096);
  
      // it starts the process on remote ssh server that 
      stream.WriteLine("startCommand"); 
      Console.Write("Waiting for any key...");
      Console.ReadKey();
  
      for (int i = 0; i &lt; 30; i++)
      {
          // Just some quick way for me to know that the device fully loaded
          stream.Expect("LogKeyWord");
      }
      Console.WriteLine("Device started");
      Console.ReadKey();
  
      // Different ways of entering commands during log output that I've tried
  
      stream.Write("5"); 
      Console.Write("Waiting for any key...");
      Console.ReadKey();
  
      stream.WriteLine("6");
      Console.Write("Waiting for any key...");
      Console.ReadKey();
  
      stream.Write("\u001b"); 
      Console.Write("Waiting for any key...");
      Console.ReadKey();
  
      var test97 = new StreamWriter(stream);
      test97.Write("7");
      Console.Write("Waiting for any key...");
      Console.ReadKey();
  
      test97.WriteLine("8");
      Console.Write("Waiting for any key...");
      Console.ReadKey();
  
      client.RunCommand("11");
      Console.Write("Waiting for any key...");
      Console.ReadKey();
  
      var test = client.CreateCommand("31");
      test.Execute();
      Console.Write("Waiting for any key...");
      Console.ReadKey();
  
      client.Disconnect();
  }
  </code></pre>