Consoleの文字化け対策 CoreCLR

昨日のテストで、文字化けしていましたが、これを対策します。

答えは簡単で、エンコードの問題でした。

まず、コンソールのエンコードを見てみます。

932、Shift-JISとなっています。これに対して、System.Consoleのエンコーディングを見てみます。

UTF-8となっています。つまり、UTF-8として出力されたものをShift-JISとして表示しようとしているので、おかしくなっていると考えられます。あわせてしまえばよいですね。一人でやってる分にはConsoleのエンコードを変えるという選択肢もあるかもしれません。ただ、そうしてしまうと個々の環境で設定が必要になってしまうため、コード側で対策しておきたいところです。なので、System.Consoleのエンコードを変えてみます。

var enc = System.Text.Encoding.GetEncoding(932);
var writer = new System.IO.StreamWriter(Console.OpenStandardOutput(), enc);
Console.SetOut(writer);

としたいところなのですが、実はこれだと動きません。

NotSupportedException
No data is available for encoding 932. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method.

何やら、エラーがSystem.Text.Encoding.RegiterProviderメソッドを見ろといっています。ここの説明では

.NET Framework 4.61 つのエンコード プロバイダーが含まれています。 T:System.Text.CodePagesEncodingProvider、を行う、利用可能なエンコーディングでは使用できませんが、完全な .NET Framework に存在を.NET Framework 4.6です。既定では、.NET Framework 4.6のみ、Unicode エンコーディング、ASCII、およびコード ページ 28591 をサポートします。

この「のみ」にすこし違和感ありますが、日本語は含まれていないようです。28591は西ヨーロッパ言語 (ISO)ですね。というわけで、そもそも、日本語は既定でサポートされていません。デスクトップ同様のサポートを確保するためには、System.Text.CodePagesEncodingProviderを利用してねーという内容ですかね。このクラスには、Instanceという静的なプロパティが一つ。これをエラーの内容に従って追加してみましょう。

System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
var enc = System.Text.Encoding.GetEncoding(932);
var writer = new System.IO.StreamWriter(Console.OpenStandardOutput(), enc);
Console.SetOut(writer);

という感じにしてみました。いざ、実行!

あれ!きれいですね。何も出てこないとなるのですが、これはバッファにFlushがかからないために出てこなくなるようです。なので、AutoFlushを有効にしちゃいましょう。

System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
var enc = System.Text.Encoding.GetEncoding(932);
var writer = new System.IO.StreamWriter(Console.OpenStandardOutput(), enc);
writer.AutoFlush = true;
Console.SetOut(writer);

という感じにプロパティの設定を追加。再び!

無事に日本語を拝めました。注意として、ここの実装だけだと、強制的にShiftJISとしてしまうので、Linuxで動かしたときは、逆に文字化けしてしまう可能性があります。また、日本語ではないWindowsでも同じことが言えます。様々なプラットフォームで動かすためには、以下を考慮しておいてみるとよいのではないかと思います。

  • 実行しているOSが、Windowsか?
  • 日本語で動いているか?
それでは!