by Michael S. Kaplan, published on 2012/04/09 07:01 -04:00, original URI: http://blogs.msdn.com/b/michkap/archive/2012/04/09/10291883.aspx
The question was simple enough:
I have a cmd line tool. On French Windows its output is correct in the cmd window but when I redirect it to a file it is no longer good. I noticed that if I set the output encoding on the Console class explicitly to the default encoding then redirecting to a file works fine:
Console.OutputEncoding = Encoding.Default;
Does anyone know why the default encoding is not set by default? Is there any reason why I shouldn’t put the line above in my code?
Thanks
Wow, if there was ever a property to avoid, Encoding.Default would be it.
As the MSDN topic explains, it is the default system ANSI code page - in other words the CP_ACP, the code page used by non-Unicode Windows applications and the programs that can read/write non-Unicode files.
Like the default .TXT file type handler, NOTEPAD.EXE.
Console applications, on the other hand, use CP_OEMCP by default, which is why the described problem is happening.
Because CP_ACP and CP_OEMCP are not the same thing, for a lot of different default system locales.
And if there is anything that the CP_ACP and the CP_OEMCP have in common, it is that they both act as non-overlapping subsets of Unicode
Now some console apps can support all of Unicode, in which case CP_UTF8 is a better use of Encoding. Or it cannot support any change, in which case using Encoding.Default will be talking text that is filtered through CP_OEMCP is and then add a CP_ACP filter as well....
In the end, you should go UP to UTF-8, or least if Unicode won't work, then CP_OEMCP should be left alone....
Claudia Lawrence on 9 Apr 2012 10:22 AM:
Thank you. That really opened the kimono for me.
Michael S. Kaplan on 9 Apr 2012 6:51 PM:
Ha!
Random832 on 10 Apr 2012 1:04 PM:
Of course, this only works if you want to make a UTF-8 text file. If you want to make an OEM text file, leave it as CP_OEMCP. If you want to make an ANSI text file...
Of course, if your output is to a pipe to a tool that expects OEM text, such as, I don't know, "more", then you really do need it in CP_OEMCP. On balance it's probably best to have a specific option for making output files (in whatever encoding), use WriteConsoleW for console output, and just leave things alone if the output is a pipe.