microsoft / winget-cli

WinGet is the Windows Package Manager. This project includes a CLI (Command Line Interface), PowerShell modules, and a COM (Component Object Model) API (Application Programming Interface).
https://learn.microsoft.com/windows/package-manager/
MIT License
23.37k stars 1.45k forks source link

PowerShell ISE doesn't like WinGet #249

Open PatrickLownds opened 4 years ago

PatrickLownds commented 4 years ago
Corrupt characters in PowerShell ISE when running WinGet --help # Brief description of your issue

Run WinGet --help from PowerShell ISE elevated.

As above. Run WinGet --help or even winget visual azure in from PowerShell ISE elevated

Expected behavior

Fully readable text.

Actual behavior

Partly corrupt text. See attached screenshots.

Environment

[winget --info]
Windows Package Manager v0.1.41331 Preview
Windows: Windows.Desktop v10.0.19041.208
Package: Microsoft.DesktopAppInstaller v1.0.41331.0

Any other software? none.
jdhitsolutions commented 4 years ago

I think what you are seeing are the ANSI escape sequences being used to highight and color the output.

snerks commented 4 years ago

Do you have the option to retry, using the recently-released Windows Terminal? https://github.com/Microsoft/Terminal

Using Windows Terminal resolved an issue I saw with emoji rendering.

PatrickLownds commented 4 years ago

WinGet works fine from the command line. I've not tested Windows Terminal. However, I tend to use PowerShell ISE and this is where you see the corruption.

jdhitsolutions commented 4 years ago

The "easy" fix is to have winget emit plain text. Only use ANSI if you detect that the console or environment supports it.

danieldjewell commented 4 years ago

Perhaps it's wishful thinking, but maybe the PowerShell ISE could be updated/enhanced to support ANSI-style (VT100?) terminal control characters?

Alternatively, perhaps winget could be extended to recognize the environment (per @jdhitsolutions ) but emit the correct control sequences based on the environment? (I'm assuming that PowerShell ISE/cmd.exe/conhost implement the "traditional" methods? Certainly "Console.WriteLine()" from .NET can set the color, etc. Console.WriteLine() docs ... I recognize that winget isn't utilizing .NET but my point is that somebody in Microsoft certainly knows the control sequences... :))

jdhitsolutions commented 4 years ago

@danieldjewell Don't look for any updates to the PowerShell ISE. What you have is what you get.

megamorf commented 4 years ago

This issue can be closed since ISE will not receive anymore updates and its use of a custom conhost increases the chances of incompatibilities with 3rd party tools.

vexx32 commented 4 years ago

@megamorf many CLI tools (rightly) check for console support for ANSI (which is typically a fairly easy thing to query from the console) before emitting escape sequences.

WinGet, as a CLI tool, should do the same.

doctordns commented 4 years ago

Why can't winget have a switch to emit text that the ISE does handle.

The ISE is a supported product and it seems sub-optimal to deliberately build a tool that breaks in another supported product. IT Pros have, for over a decade, depended on the ISE. Please don't shut off support for the ISE if you can avoid it.

megamorf commented 4 years ago

@bitcrazed Could you give your input on this matter. I believe you might know the recommended way to handle the ISE console.

bitcrazed commented 4 years ago

The problem here is that command-line tools cannot accurately determine whether the terminal they're connected to supports VT (or any other capability for that matter).

While feasible locally by calling GetConsoleMode() and checking the returned flags for ENABLE_VIRTUAL_TERMINAL_INPUT, this breaks down if, for example, calling a command-line app on a remote machine via ssh.

The best fix for this would be for ISE to improve its built-in terminal to at least parse and strip VT sequences, or better still, the parse and process VT sequences.

I suggest filing an issue in the PowerShell repo, but as pointed out above, note that ISE is no longer being developed and it's likely you'll get a WONTFIX.

As an alternative, I'd recommend using VSCode with the PowerShell add-in - it's actively developed and regularly improved.

doctordns commented 4 years ago

Why not just give the user the option of whether to use VT or plain text? That way, the user can use winget irrespective of their shell.

You could ntroduce an environment variable such as WINGET_VT that says $True (use VT) or $False (use plain ascii).

Rather than asking other people/teams to do work to make winget work with their shell, why not make winget capable of being used by ALL shells with the user being able to make the choice. This is more inkeepign with the expectations of IT Pros.

bitcrazed commented 4 years ago

@doctordns Setting an ENVVAR for every command-line tool on the planet telling it whether or not to support VT is not a tenable solution? And how does winget running on a remote machine read the ENVVAR settings on your local Windows instance running ISE? Hint: it can't, so now you have to go set ENVVARS on all the remote machines you connect to. And then when you operate the remote machine locally, winget doesn't emit color ... why? Because the ENVVAR tells it not to.

However ... every other shell and terminal on the planet has supported VT since the '60s.

Heck, we even managed to get the venerable Windows Console to support VT (without breaking the world - we're rather proud of that 😜). Windows Terminal supports a superset of the VT supported by Console. Every other 3rd party Windows terminal including ConEmu, Cmder, Console2, ConsoleZ, and Hyper all support VT.

The issue here isn't winget emitting VT, it's ISE not supporting VT at all. Alas, ISE is EOL unless you can convince @SteveL-MSFT to dedicate resources to update it. If he won't, I encourage you to start learning/adopting tools that are actively developed and supported.

FWIW, in ISE as it stands, you'll also see all manner of "garbage" if you ssh into a Linux box, etc. or curl https://wttr.in/ from within ISE: image

vs. Terminal: image

vs. VSCode' s terminal panel image

vs. Visual Studio's built-in terminal panel (mostly) get it right: image

JohnMcPMS commented 4 years ago

winget does already use the MSDN suggested way to determine whether VT is supported or not, as @bitcrazed suggests. It also has a flag already to disable VT output completely (--no-vt), but it appears that I did a bad job implementing that because it still outputs VT some of the time (likely to always be the case if we fail to parse some argument). Now that we have a settings file (still waiting on release), we could also add a VT disable option to it that would be more complete at disabling VT output (short of a failure to parse the file at all). This is what I would suggest you pivot the ask to.

bitcrazed commented 4 years ago

Hey @JohnMcPMS - thanks for the update.

But again, expecting ANY command-line tool to be able to detect whether or not the terminal can handle VT will likely end in failure: The best way to figure this out is to consider the behaviors when running ISE locally to talk to a command-line of a remote machine via SSH:

In such a case, winget running on the remote machine may lookup its settings which say enable VT, and emit VT-enriched output. This output comes all the way back to ISE which shows garbage.

To circumvent this, you instead modify the config on the remote machine to tell winget NOT to emit VT, which works, but then diminishes the local experience at the remote machine. Plus it doesn't fix the issue for any other command-line app or script that might `emit VT.

The only way to fix this is for ISE to either filter-out VT from incoming text, or to implement at least basic VT support. But as @SteveL-MSFT points out, the team don't have the resources to apply to this effort since ISE is in maintenance mode.

One possible work-around here is to write a tool/cmdlet into which one can pipe VT enriched text, and which strips out the VT sequences, emitting plain text, e.g. winget install foo | novt

So, once again, the best way around this is to adopt other tools (e.g. Windows Terminal) and PowerShell dev environments (e.g. VSCode) that are being actively developed, and do a good job of supporting command-line scenarios.