Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

C# StandardInput.WriteLine() is sending strange characters to external console application - SOLVED.

Discussion in 'Scripting' started by Akanaro, Jun 9, 2016.

  1. Akanaro

    Akanaro

    Joined:
    Oct 26, 2014
    Posts:
    12
    Hi,

    I am attempting to use StandardInput.WriteLine (System.Diagnostics NameSpace) to send commands to a chess engine exe. It works great except that for some reason some gibberish (nonsense) characters are send with the actual commands which shouldn't be there. I tested the code in Visual Studio and it works just fine but when running it with Unity the input string seems to obtain some extra baggage. I thought it might be a problem with the chess engine but it does the same when sending strings to the standard windows console and like I said, the code works flawlessly in Visual Studio. The weird characters look like this .

    Any ideas?

    Edit - I stumbled upon a workaround. If I use BaseStream.Write instead, send "\n" afterwords and then do StandardInput.Write(KeyCode.Return) it actually works. No gibberish! It's not pretty but it works for now. I'd still like to find the root of the problem though. It looks like whenever StandardInput tries to send it's own newline string something gets mangled.
     
    Last edited: Jun 9, 2016
  2. jimroberts

    jimroberts

    Joined:
    Sep 4, 2014
    Posts:
    560
    Sounds like an encoding issue. I would like to know the results of writing your string with StandardInput.Write(stringHere) and then StandardInput.Write(Environment.NewLine) immediately after.
     
  3. Akanaro

    Akanaro

    Joined:
    Oct 26, 2014
    Posts:
    12
    Thanks for replying Jim.

    Environment.Newline produces the same unwanted characters. The only option that is working right now is per the code below.

    Code (CSharp):
    1.  
    2.             Process UciEngine = new Process();
    3.             UciEngine.StartInfo.FileName = path;
    4.             UciEngine.StartInfo.CreateNoWindow = false;
    5.             UciEngine.StartInfo.UseShellExecute = false;
    6.             UciEngine.StartInfo.RedirectStandardInput = true;
    7.             UciEngine.StartInfo.RedirectStandardOutput = false;
    8.             UciEngine.StartInfo.RedirectStandardError = true;
    9.  
    10.                      
    11.             if (UciEngine.Start()){
    12.  
    13.                 byte[] buffer = System.Text.Encoding.ASCII.GetBytes("uci");
    14.                 UciEngine.StandardInput.BaseStream.Write(buffer, 0, buffer.Length);
    15.                 buffer = System.Text.Encoding.ASCII.GetBytes("\n");
    16.                 UciEngine.StandardInput.BaseStream.Write(buffer, 0, buffer.Length);
    17.                 UciEngine.StandardInput.Write(KeyCode.Return);
    18.  
    19.             }
    20.  
    If I try do do the same using StandardInput.Write instead I again get the same bad result. StandardOutput was not redirected so I could see what ends up getting send because I wasn't getting the expected response to the "uci" command. Like I said, it's odd that the problem only seems to occur in Unity (MonoDevelop) as I have no problems when using the StandardInput.Write command in Visual Studio.
     
    Last edited: Jun 10, 2016
  4. jimroberts

    jimroberts

    Joined:
    Sep 4, 2014
    Posts:
    560
    What is the result of StandardInput.Encoding.EncodingName? You probably just need to set the Console.OutputEncoding to match with StandardInput.
     
    Last edited: Jun 11, 2016
  5. Akanaro

    Akanaro

    Joined:
    Oct 26, 2014
    Posts:
    12
    StandardInput.Encoding.EncodingName returns UTF-8. I tried setting Console.OutputEncoding to match but the problem remains.
     
  6. jimroberts

    jimroberts

    Joined:
    Sep 4, 2014
    Posts:
    560
    That's quite odd... I decided to do a little more research on the problem but came up empty. However, the MSDN suggests using a StreamWriter for redirecting the StandardInput stream.

    Code (CSharp):
    1. StreamWriter s = process.StandardInput;
    2.  
    3. s.WriteLine("line");
     
  7. Akanaro

    Akanaro

    Joined:
    Oct 26, 2014
    Posts:
    12
    Thanks Jim, your last post helped to solve the problem. What I needed to do was:

    Code (CSharp):
    1. StreamWriter myStream = new StreamWriter(UciEngine.StandardInput.BaseStream, Encoding.ASCII);
    2. myStream.WriteLine("uci");
    3. myStream.Close();
    So it was as you expected, and encoding issue. Now I can write pretty code instead of butcher code. :p
     
    cp_sn likes this.
  8. cp_sn

    cp_sn

    Joined:
    Aug 24, 2015
    Posts:
    4
    ASCII it is, thanks a lot