You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This explanation applies to command-line programs running on Windows that use this module (gopkg.ilharper.com/x/isatty). Other programs fall outside of the scope of this issue.
History
The Console
ConHost.exe, which was recently open sourced and renamed to OpenConsole.exe, is the only console program on Windows. When you start your command-line program, Windows (we'll only discuss cases before 22H2 for convenience) creates a new ConHost.exe instance and attaches it to the newly launched program. ConHost and command-line program exchanges text data as IOCTL messages via the kernel-mode Console Driver (ConDrv), making it difficult for "3rd-party terminal"s to hijack this process. This including 3rd-party terminals like Mintty (also known as "Git Bash"), IDEs like VSCode and even the "Microsoft 1st-party" Windows Terminal.
3rd-party PTYs
Many people have tried various means to solve this problem, by creating a "Pseudo Terminal" (PTY). Cygwin made a set of PTY APIs which behave like PTYs on *nix systems, but it requires recompiling the whole program with Cygwin, which is not suitable for us.
Another widely used solution is winpty, which creates an off-screen ConHost, send user-typed keystrokes to it, and screen-scrape the console’s text. Many programs use this solution.
The Windows Pseudo Console (ConPTY)
In Windows 10 1809, Microsoft refactored the command-line logic of Windows and added a set of PTY APIs in Windows SDK, which is called ConPTY. Many terminal programs have upgraded and added options to adopt in this new ConPTY, including Mintty and VSCode. Windows Terminal uses OpenConsole.exe and ConPTY only.
Solutions
Here are the solutions to this issue, each requiring action by the end user:
Launch your program directly in cmd.exe attached by ConHost.exe. This way you'll have a REAL console which is definitely a TTY.
Use ConPTY-only terminals such as Windows Terminal. ConPTY is the only way they create console and you'll get a pseudo terminal which is a TTY.
Enable ConPTY in terminal options. For Mintty, set ConPTY=true in .minttyrc. Note especially that for MSYS2, you may need to set the environment variable MSYS=enable_pcon, although MSYS2 is not a terminal program. You also need to be aware that setting multiple values to MSYS such as MSYS=winsymlinks:nativestrict:enable_pcon will have no effect. this may be a bug.
Use winpty as a wrapper, such as winpty myapp.
Can you just detect the terminal and return "there's a TTY"?
No. There are many "pipe operations" in shell programs such as myapp > a.txt so your os.Stdout may not necessarily be the stdout of the terminal. There's really nothing I can do other than call the API of the OS. This is not something that program in user-mode area can do.
For WSL Users
You must use a terminal that directly supports WSL, such as ConHost, Windows Terminal and WSLtty.
This explanation applies to command-line programs running on Windows that use this module (
gopkg.ilharper.com/x/isatty
). Other programs fall outside of the scope of this issue.History
The Console
ConHost.exe
, which was recently open sourced and renamed toOpenConsole.exe
, is the only console program on Windows. When you start your command-line program, Windows (we'll only discuss cases before 22H2 for convenience) creates a newConHost.exe
instance and attaches it to the newly launched program. ConHost and command-line program exchanges text data as IOCTL messages via the kernel-mode Console Driver (ConDrv
), making it difficult for "3rd-party terminal"s to hijack this process. This including 3rd-party terminals like Mintty (also known as "Git Bash"), IDEs like VSCode and even the "Microsoft 1st-party" Windows Terminal.3rd-party PTYs
Many people have tried various means to solve this problem, by creating a "Pseudo Terminal" (PTY). Cygwin made a set of PTY APIs which behave like PTYs on *nix systems, but it requires recompiling the whole program with Cygwin, which is not suitable for us.
Another widely used solution is winpty, which creates an off-screen ConHost, send user-typed keystrokes to it, and screen-scrape the console’s text. Many programs use this solution.
The Windows Pseudo Console (ConPTY)
In Windows 10 1809, Microsoft refactored the command-line logic of Windows and added a set of PTY APIs in Windows SDK, which is called ConPTY. Many terminal programs have upgraded and added options to adopt in this new ConPTY, including Mintty and VSCode. Windows Terminal uses
OpenConsole.exe
and ConPTY only.Solutions
Here are the solutions to this issue, each requiring action by the end user:
Launch your program directly in
cmd.exe
attached byConHost.exe
. This way you'll have a REAL console which is definitely a TTY.Use ConPTY-only terminals such as Windows Terminal. ConPTY is the only way they create console and you'll get a pseudo terminal which is a TTY.
Enable ConPTY in terminal options. For Mintty, set
ConPTY=true
in.minttyrc
. Note especially that for MSYS2, you may need to set the environment variableMSYS=enable_pcon
, although MSYS2 is not a terminal program. You also need to be aware that setting multiple values to MSYS such asMSYS=winsymlinks:nativestrict:enable_pcon
will have no effect. this may be a bug.Use winpty as a wrapper, such as
winpty myapp
.Can you just detect the terminal and return "there's a TTY"?
No. There are many "pipe operations" in shell programs such as
myapp > a.txt
so youros.Stdout
may not necessarily be the stdout of the terminal. There's really nothing I can do other than call the API of the OS. This is not something that program in user-mode area can do.For WSL Users
You must use a terminal that directly supports WSL, such as ConHost, Windows Terminal and WSLtty.
References
The text was updated successfully, but these errors were encountered: