consoleframework
consoleframework copied to clipboard
Framework doesn't work in GitBash terminal emulator
Programs using the consoleframework can't run in terminal emulators, like GitBash command prompt. An Exception is thrown (invalid handle) at the start of the program.
Reproduction steps
- Have a small program, like:
using ConsoleFramework;
using ConsoleFramework.Controls;
namespace CrashTest
{
class Program
{
static void Main(string[] args)
{
WindowsHost windowsHost = new WindowsHost();
Window window = new Window();
window.Content = new TextBlock
{
Text = "This will crash in Terminal Emulator"
};
windowsHost.Show(window);
ConsoleApplication.Instance.Run(windowsHost);
}
}
}
- Compile it and try to execute it GitBash terminal
./CrashTest.exe
Result:
Unhandled exception. System.IO.IOException: Invalid handle.
at System.ConsolePal.GetBufferInfo(Boolean throwOnNoConsole, Boolean& succeeded)
at System.Console.get_WindowLeft()
at ConsoleFramework.ConsoleApplication.runWindows(Control control)
at ConsoleFramework.ConsoleApplication.Run(Control control)
at CrashTest.Program.Main(String[] args) in Program.cs:line 18
Expected:
UI, like in Windows Command prompt (cmd.exe)
I think GuiBash is not the best choice to run TUI apps compiled for Windows )
GuiBash is designed to run cross-compiled unix programs and does not guarantee that all win32 api will be available inside it. But console-framework app compiled for Windows tries to use Win32 console api, not unix api (cross-compiled libc, ncurses).
I think on Windows there is better option to run console-based TUI apps on standard cmd terminal.
For example, Far Manager doesn't work in the "Git Bash" (mintty terminal emulator, actually) directly, either.
There's a special wrapper program that converts observable WinAPI console behavior to ANSI terminal commands, which is called winpty
. It is available in the Git Bash environment, and Windows programs with TUI based on WinAPI (e.g. Far Manager or programs written using ConsoleFramework) are runnable via winpty
, I've just checked both.
Just run winpty
followed by your program arguments, and it will work:
It would be cool to have ConsoleFramework run in "pure ANSI" mode on top of any ANSI-compatible terminal, because, since Windows 10, the native conhost
is ANSI-compatible, too. I'm not sure if it's a viable approach to suggest that improvement though. It looks like we still need some stuff from environment, like terminal size and such, which couldn't be easily retrieved using the "pure ANSI" approach, and would probably require some additional measures to link against mintty environment.
Mouse doesn't seem to work well under winpty, though: when I click the top of the window (point 1 on the picture below), it registers click on the top of the ConsoleFramework canvas (point 2):
Probably this is something which could be improved, because Far Manager works perfectly with this setup: it eats the whole buffer (maybe because it prints text to the whole buffer, while the canvas of my test ConsoleFramework program was mostly empty), and mouse clicks are registered properly.
I believe we could introduce a compatibility hack for mintty: print a character to the very end of our buffer to force terminal scrolling and reduce the amount of mouse-related bugs. It could be introduced manually by program authors though, and I don't know a reliable way to detect mintty terminal environment: it reports TERM=xterm
.
And, for the record, I've found some crazy Haskell code that detects whether the program is running in mintty by messing with stderr handle. Not sure if we want the mintty workaround that much though :)