title: .Net RedirectStandardOutput and RedirectStandardInput are overlapping
body: <p>I am writing a prototype application that will require redirecting the stdin and stdout streams of a command-line application to a different application, and it kind of works. However, there is some annoying behavior which I cannot seem to work around. Anything written to the StandardInput stream also appears in the StandardOutput stream.</p>
  <p>Using command prompt as an example, I would write, the following into the StandardInput stream:</p>
  <pre><code>C:\Users\Me&gt;echo Hello
  </code></pre>
  <p>and then on StandardOutput, I read the following:</p>
  <pre><code>echo Hello
  Hello
  </code></pre>
  <p>For more examples:</p>
  <pre><code>C:\Users\Me&gt;ls
  ls
  'ls' is not recognized as an internal or external command, operable program or batch file. 
  C:\Users\Me&gt;whoami
  whoami
  domain\Me
  C:\Users\Me&gt;NonSensicalCommand fooArgs fooArg1 forArg2 ImAlittleTeapot
  NonSensicalCommand fooArgs fooArg1 forArg2 ImAlittleTeapot 
  'NonSensicalCommand' is not recognized as an internal or external command, operable program or batch file.
  </code></pre>
  <p>This seems to be universal, to any application where I redirect the streams. I have tried with cmd, Plink, and some personal CLI items I've written. Anything and everything written to StandardInput always shows up in StandardOutput.</p>
  <p>Is there something I can do which would keep these two streams separate? I've tried starting with things like &quot;echo off&quot;, but that doesn't accomplish anything.</p>
  <p>The following is my code (again, using cmd as an example; to run with plink, swap the PSI lines)</p>
  <pre class="lang-C# prettyprint-override"><code>using System;
  using System.Diagnostics;
  using System.IO;
  using System.Text;
  using System.Threading;
  
  static void Main( string[ ] args )
  {
      ProcessStartInfo psi = new ProcessStartInfo( &quot;C:\\Windows\\System32\\cmd.exe&quot; );
  
      // If you'd like to run the code with the Plink, use the below line instead
      //ProcessStartInfo psi = new ProcessStartInfo( &quot;C:\\Program Files\\PuTTY\\plink&quot; ,
      //&quot;-ssh someUser@SshServer.SomeDomain.com -pw FooPass&quot; );
  
      psi.RedirectStandardInput = true;
      psi.RedirectStandardOutput = true;
      psi.WindowStyle = ProcessWindowStyle.Normal;
      psi.UseShellExecute = false;
      psi.CreateNoWindow = false;
  
      Process process = new Process( );
      process.StartInfo = psi;
      process.Exited += Process_Exited;
      process.EnableRaisingEvents = true;
      process.Start( );
      process.StandardInput.NewLine = &quot;\n&quot;; // using \r\n causes confusion in the Unix environment; just use \n
      process.StandardInput.AutoFlush = true;
  
      // [Lines 30 -&gt; 42] Async Routine constantly reads stdout and prints to screen; reads a sinlge byte, then reads again.
      AsyncCallback stdOutCallback = null;
      byte[ ] myBuffer = new byte[1];
  
      stdOutCallback = asyResult =&gt;
      {
          int bytesRead = process.StandardOutput.BaseStream.EndRead( asyResult );
  
          Console.Write( Encoding.ASCII.GetString( myBuffer ) );
  
          process.StandardOutput.BaseStream.BeginRead( myBuffer, 0, 1, stdOutCallback, null );
      };
      
      process.StandardOutput.BaseStream.BeginRead( myBuffer, 0, 1, stdOutCallback, null );
      
      
      // Writing to StandardInput exists inside a dedicated thread which will be handed the process
      new Thread( WriteToInput ).Start( process );
      
      // Wait for controlled process to exit
      process.WaitForExit( );
  }
  
  // Raisable event; current application exits with the same exit code as connected process
  static void Process_Exited( object sender, EventArgs e )
  {
      Environment.Exit( ((Process)sender).ExitCode );
  }
  
  // Constant loop which reads console input and writes it to connected process StandardInput
  static void WriteToInput( object targ )
  {
      Process process = (Process)targ;
      
      string input = Console.ReadLine( );
      
      while ( input != &quot;---&quot; )
      {
          process.StandardInput.WriteLine( input );
          input = Console.ReadLine( );
      }
  }
  </code></pre>