Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

After calling the Process program, the console input cannot be displayed on the terminal #43866

Closed
ymh199478 opened this issue Oct 27, 2020 · 5 comments
Labels
area-System.Console os-linux Linux OS (any supported distro)

Comments

@ymh199478
Copy link

ymh199478 commented Oct 27, 2020

Description

hello, I'm not sure if it is a bug, but it seems to be behaving very strangely. This problem only occurs under linux, and the window can run as expected.

I call a git command through Process, and then ReadKey (or read input with input stream) from the console. Under Linux, user input is hidden(Similar to password input). I expect user input can be seen on the terminal.

I reproduced a minimal example the code is as follows, you can also get the complete project through github repo.

static void Main(string[] args)
{
        var inputStream = Console.OpenStandardInput();
        Console.SetIn(new StreamReader(inputStream));

        ListReference();

        Console.WriteLine("Please enter something first:");
        var line = Console.ReadLine();
        Console.WriteLine($"read first: {line}");

        Console.WriteLine("Please enter something second:");
        line = ReadInput(inputStream);
        Console.WriteLine($"read second: {line}");
}

private static void ListReference()
{
       var process = new System.Diagnostics.Process
       {
           StartInfo =
           {
                  FileName = "git",
                  CreateNoWindow = true,
                  UseShellExecute = false,
           },
       };

       var command = "show-ref --head -d";
       process.StartInfo.Arguments = command;
       process.StartInfo.WorkingDirectory = Path.Combine(Environment.CurrentDirectory, "repo");
       process.Start();
       process.WaitForExit();
       process.Close();
 }

private static string ReadInput(Stream inputStream, Encoding encoding = null)
{
       string ret = null;
       encoding ??= Encoding.UTF8;

       // We only correct the position when we allow seek.
       long position = 0;
       if (inputStream.CanSeek)
       {
           position = inputStream.Position;
       }

       using (var reader = new StreamReader(inputStream, encoding,
                true, 128, true))
       {
           ret = reader.ReadLine();

           // We skip this step directly when it is not allowed,
           // because there will be no bugs even if you do not
           // use position correction under the console program.
           // It contains a potential problem: !5
           if (inputStream.CanSeek && !(ret is null))
           {
                 inputStream.Seek(
                        position + encoding.GetByteCount(ret.ToString()) + encoding.GetByteCount(Environment.NewLine),
                        SeekOrigin.Begin);
           }
       }

       return ret;
}

The value of variable line will be the value entered in the terminal,The program can get the input value correctly but when the key is pressed, it will become like a password input. In other words the entered characters are not displayed in the terminal, until after pressing Enter, the program can receive the input value.

If the function ListReference is annotated, it can also run as expected under linux.

The same code under windows and linux resulted in different behaviors. This confused me. Did I do something wrong?

Configuration

  • Running computer
$ dotnet --info
It was not possible to find any installed .NET Core SDKs
Did you mean to run .NET Core SDK commands? Install a .NET Core SDK from:
      https://aka.ms/dotnet-download

Host (useful for support):
  Version: 3.1.7
  Commit:  fcfdef8d6b

.NET Core SDKs installed:
  No SDKs were found.

.NET Core runtimes installed:
  Microsoft.NETCore.App 3.1.7 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download
$ uname -a
Linux e3e3b80e6c3c 3.10.0-514.el7.x86_64 #1 SMP Tue Nov 22 16:42:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

Other information

I guess whether it is due to some behavior in Process that affects the Console.

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-System.Console untriaged New issue has not been triaged by the area owner labels Oct 27, 2020
@ghost
Copy link

ghost commented Oct 27, 2020

Tagging subscribers to this area: @eiriktsarpalis, @jeffhandley
See info in area-owners.md if you want to be subscribed.

@eiriktsarpalis
Copy link
Member

I can reproduce this in .NET Core 3.1, but not on .NET 5. Minimal repro:

using System;
using System.IO;
using System.Diagnostics;

namespace ConsoleApp4
{
    class Program
    {
        static void Main(string[] args)
        {
            var inputStream = Console.OpenStandardInput();
            Console.SetIn(new StreamReader(inputStream));

            var process = Process.Start("ls");
            process.WaitForExit();

            Console.WriteLine("Please enter something first:");
            var line = Console.ReadLine();
            Console.WriteLine($"read first: {line}");
        }
    }
}

@tmds I presume this was fixed by #39192?

@eiriktsarpalis eiriktsarpalis added os-linux Linux OS (any supported distro) and removed untriaged New issue has not been triaged by the area owner labels Oct 27, 2020
@ymh199478
Copy link
Author

Is there an alternative to the 3.x version to solve this problem?

@eiriktsarpalis
Copy link
Member

In my tests I was able to make the issue go away by not setting a custom In reader. Is that something you could do in your app?

@tmds
Copy link
Member

tmds commented Oct 28, 2020

@tmds I presume this was fixed by #39192?

Yes.

Is there an alternative to the 3.x version to solve this problem?

You can do something that makes .NET Core turn off echoing (I think getting Console.KeyAvailable should be enough), and from then on echo yourself anything read from Console.OpenStandardInput Stream by calling Console.Write*.

@ghost ghost locked as resolved and limited conversation to collaborators Dec 6, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Console os-linux Linux OS (any supported distro)
Projects
None yet
Development

No branches or pull requests

4 participants