powershellconsolewrite-host

Write-Host with background colour fills the entire line with background colour when window is resized in powershell


eg, if you execute this command in a powershell session

write-host 'hello' -ForegroundColor 'red' -BackgroundColor 'cyan'

resizing the window causes the background colour to fill the entire line:

enter image description here

I have tested this in Windows Terminal, Windows Console and Fluent Terminal and they all exhibit this behaviour. (I am guessing there could be a virtual terminal sequence/ANSI code to fix this issue, but I have no idea what this could be).

So, how can we prevent this from happening?

λ $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.1.1
PSEdition                      Core
GitCommitId                    7.1.1
OS                             Microsoft Windows 10.0.19041
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

EDIT: As a test I tried the following:

write-host 'hello' -ForegroundColor 'red' -BackgroundColor 'cyan' -NoNewline; write-host 'world' -BackgroundColor black

which of course displays 'HelloWorld', with 'World appearing without a background colour or more accurately the same as the default (black).

If we take this another step forward and print an extra space after with the background colour set to black, then this does not achieve the desired response, IE we're back to seeing the background colour cyan filling the entire line after a resize occurs.

So we need some kind of non visible character that blocks the overspill of the background colour or an entirely different approach of which I'm not currently aware.


Solution

  • This is confirmed bug in conhost from 2017. So, everything that relies on conhost will have this bug.

    This is a bug in windows console, not in powershell. It is buggy outside powershell (try this, ex).

    Console fills line with color of last character that is not space (0x20), nor tab (0x09), nor newline.

    You can try one of solutions:

    1 - Use Non-Breaking space character space at the end of line. This is the only space one-byte character that is space, and that is not ignored by console, and that is not line break.

    write-host 'hello' -f 'red' -b 'cyan' -n;   write-host ([char]0xA0)
    

    2 - Use any character with color matching console colors. This is worse as it is copied to clipboard, to output, etc.

    $hostBgColor = $Host.UI.RawUI.BackgroundColor
    write-host 'hello' -f 'red' -b 'cyan' -n;   write-host 'X' -f $hostBgColor -b $hostBgColor
    

    3 - Use other unicode multi-byte whitespace characters, but they can look different depending on many factors, including fonts and unicode support int console\output file.