What happened
I hosted CliHost inside a WinForms app (tig/mcec#252): OutputType=WinExe, with the classic hybrid pattern of AttachConsole(ATTACH_PARENT_PROCESS) when args are present so --help/--version/--opencli print to the parent terminal.
--version and --opencli were fine, but myapp help printed the rendered help with ANSI escapes as literal text ([39m[49m[1m## Commands...), and the mangled lines wrapped, wrecking the table layout.
Root cause
MarkdownRenderer.RenderToAnsi writes VT escape sequences produced by Driver.ToAnsi(). Every shipped host (greet, clet, the survey example in #9) is a console-subsystem app, which inherits a console session whose output mode the shell/terminal already set up (VT processing on). A GUI-subsystem process that attaches to a console does not get ENABLE_VIRTUAL_TERMINAL_PROCESSING on its output, so conhost renders the escape bytes as text.
The fix on the host side is one call after AttachConsole:
IntPtr stdout = GetStdHandle(STD_OUTPUT_HANDLE);
if (GetConsoleMode(stdout, out uint mode)) {
SetConsoleMode(stdout, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
}
Suggestions
- Docs: add a "Hosting from a GUI app (WinExe)" section to the README/library spec: AttachConsole + enable VT processing, plus the caveat that the shell prompt returns immediately for a WinExe. None of the examples cover this shape, and it is a natural one for TG.Cli (an existing GUI app that wants a scriptable CLI surface without becoming a console app).
- Library (optional but nicer):
MarkdownRenderer.RenderToAnsi already fixes up the console when writing to the real console (Console.OutputEncoding → UTF-8). Enabling VT processing on Windows in that same spot would make every host correct by construction, including hybrids, with no behavior change for console apps (the flag is already set there).
Happy to PR either.
What happened
I hosted
CliHostinside a WinForms app (tig/mcec#252):OutputType=WinExe, with the classic hybrid pattern ofAttachConsole(ATTACH_PARENT_PROCESS)when args are present so--help/--version/--opencliprint to the parent terminal.--versionand--opencliwere fine, butmyapp helpprinted the rendered help with ANSI escapes as literal text ([39m[49m[1m## Commands...), and the mangled lines wrapped, wrecking the table layout.Root cause
MarkdownRenderer.RenderToAnsiwrites VT escape sequences produced byDriver.ToAnsi(). Every shipped host (greet, clet, the survey example in #9) is a console-subsystem app, which inherits a console session whose output mode the shell/terminal already set up (VT processing on). A GUI-subsystem process that attaches to a console does not getENABLE_VIRTUAL_TERMINAL_PROCESSINGon its output, so conhost renders the escape bytes as text.The fix on the host side is one call after
AttachConsole:Suggestions
MarkdownRenderer.RenderToAnsialready fixes up the console when writing to the real console (Console.OutputEncoding→ UTF-8). Enabling VT processing on Windows in that same spot would make every host correct by construction, including hybrids, with no behavior change for console apps (the flag is already set there).Happy to PR either.