2

Why does the tree command look different on Powershell than what it does on Cmd.

Powershell vs cmd tree command

mklement0
  • 382,024
  • 64
  • 607
  • 775
SaTown
  • 25
  • 1
  • 3
  • Try another font. Consolas for example. – Olaf Apr 29 '20 at 22:57
  • 1
    use the `/a` option to use text chars instead of graphics chars. the reason is that the PoSh console does not support the same character set unless you find a way to tell it to do so ... and i can't find any way to do that at this time. – Lee_Dailey Apr 29 '20 at 23:16
  • PS is using ANSI or Unicode and CMD using OEM (aka DOS) –  Apr 30 '20 at 00:05
  • @Olaf It's a character-encoding problem, so choosing a different font won't help. – mklement0 Apr 30 '20 at 15:59
  • @Lee_Dailey Note that the problem only affects the ISE; setting `[Console]::OutputEncoding` to the OEM code page fixes it; see my answer for details. – mklement0 Apr 30 '20 at 16:00
  • @Mark When decoding output from external programs, PowerShell does honor the active OEM - except in the ISE, where the ANSI code page is used by default. – mklement0 Apr 30 '20 at 16:01

2 Answers2

0
  • The problem only occurs in the PowerShell ISE, where output from external programs such as tree.com isn't passed straight through to the console.

  • To fix it, you must (temporarily) change [Console]::OutputEncoding to match your system's active OEM legacy code page, because that is the character encoding tree.com uses:

# Switch the encoding that PowerShell expects external programs to use
# to the active OEM code page.
[Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding(
  [cultureinfo]::CurrentCulture.TextInfo.OEMCodePage
)

# tree.com now produces the expected output in the ISE
tree

Note:

  • Even in a regular console window / Windows Terminal window and in Visual Studio Code [Console]::OutputEncoding can come into play, but only when you capture or redirect an external program's output (e.g., $treeOutput = tree or tree | ...).

    • As indicated above, this is not necessary for direct-to-display output - except in the ISE, where [Console]::OutputEncoding matters even then, which default to the system's active ANSI legacy code page.
  • For PowerShell to correctly interpret an external program's output when capturing or redirecting it, [Console]::OutputEncoding must match the actual encoding used by that program.

Therefore, if you want to capture or redirect tree.coms output, you may have to set [Console]::OutputEncoding:

In short, unless [Console]::OutputEncoding.CodePage matches the code-page number reported by [cultureinfo]::CurrentCulture.TextInfo.OEMCodePage - e.g., 437 on US-English systems - setting [Console]::OutputEncoding is needed.

  • In console windows and Windows Terminal windows this is generally not necessary (as of PowerShell 7.0) - it is only necessary if you've explicitly changed the active code page to UTF-8, for instance - see this answer; note that UTF-8 may become the default over time.

  • In Visual Studio Code, however, it is necessary by default, because in the PowerShell Integrated Console [Console]::OutputEncoding defaults to UTF-8 (code page 65001).

mklement0
  • 382,024
  • 64
  • 607
  • 775
-1

I believe it's because it's one of those commands that PowerShell runs cmd for in the background then pipes the output to Write-Host, similar to ping or ipconfig

  • `tree.com` is an external executable, which PowerShell invokes directly - no involvement of `cmd.exe`. In console windows and Visual Studio Code's PowerShell Integrated Terminal, output from external programs is _passed through_ to the console (unless captured or redirected). In the ISE, by contrast, the output is first internally captured and decoded, and then printed to the display (though I doubt that actual `Write-Host` calls are involved). – mklement0 Apr 30 '20 at 15:58