WSL powershell.exe Output Encoding Problem

---
date: Feb 02, 2021
tags:
-
-
---

Well well well, here we go again.

I recently received a bug report that when there are umlauts in their username (wslutilities/wslu#162), wslusc failed to copy the file. In his case, the username is “StephanHochdörfer,” and the output is the following:

1
2
3
4
5
6
...
[warn] wsl.ico not found in Windows directory. Copying right now...
mkdir: cannot create directory '/mnt/c/Users/StephanHochd\224rfer/wslu': No such file or directory
cp: cannot create regular file '/mnt/c/Users/StephanHochd'$'\224''rfer/wslu': No such file or directory
[info] wsl.ico copied. Located at "/mnt/c/Users/StephanHochd�rfer/wslu".
...

Oh no! Anyway...

Oh no! Anyway, it’s related to the code page mess in our good old powershell.exe —- what a great sequel to our powershell raster font problem.

From last time, we already get a pretty good structure that solves raster font, so we will expand from there:

1
2
3
4
oemcp=$(reg.exe query "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage" /v OEMCP 2>&1 | sed -n 3p | sed -e 's|\r||g' | grep -o '[[:digit:]]*')
chcp.com $oemcp
powershell.exe ...
chcp.com 65001

powershell.exe has an interesting way in its input/output encoding, that it will follow the system code page. You can type [Console]::OutputEncoding and [Console]::InputEncoding in Powershell, and you can see what language/encoding/code page your console is currently using (Mine here is already corrupted during the debugging):

My messed up encoding

However, As we mentioned in powershell raster font problem article, we need UTF-8 all the time. Thus, we can force input to follow your system language by using [Console]::InputEncoding = [System.Text.Encoding]::GetEncoding(<codepage>) command, where codepage is… well… code page; we can then force the output to use UTF-8 by using [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 command. Both commands should be executed before executing your command, so it should be something like this:

1
powershell.exe ... -Command "[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; [Console]::InputEncoding = [System.Text.Encoding]::GetEncoding(<codepage>); <command>"

Combining from the base, we got the following:

1
2
3
4
5
oemcp=$(reg.exe query "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage" /v OEMCP 2>&1 | sed -n 3p | sed -e 's|\r||g' | grep -o '[[:digit:]]*')
chcp.com $oemcp
oemcp=$(($oemcp+0))
powershell.exe ... -Command "[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; [Console]::InputEncoding = [System.Text.Encoding]::GetEncoding($cp); <command>"
chcp.com 65001

And now the problem is now gone! Following is demo of the fixed bug in wslu:

Now I wish there won’t be another sequel to this problem…

Navigation


Creative Commons License
Unless specified, all the articles are licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

The site is proudly powered by Hexo hosted on DigitalOcean App Platform.

The site is powered by the glorious CSS from bettermotherf**kingwebsite.com with some tweaks. Censored the f-word for good.

The source code of this website is hosted at patrick330602/blog-source, so that you can see the spaghetti code behind my blog.

Main | Access | CDN | RSS | Sitemap
2008 - 2021 | Patrick WU Jinming