だいぶ予定が遅れたようだが、 .NET Core 1.0 の RC2 が5月中旬にリリースされた。
2000年に初めて .NET がリリースされてから、 mono が登場したりといったことはあったものの、 16年越しでついに クロスプラットフォームのアプリケーションを作成できる環境が、マイクロソフト公式から提供された。
ということで、さっそく .NET から VS2015 DotNetCore Tools Preview 1 をインストールして、 Hello World を書いてみよう。
using System;
using System.Text;
namespace netcore_console_test_01 {
public class Program {
public static void Main(string[] args) {
Console.WriteLine("はろー わ~るど!");
}
}
}
…文字化けするぞ!!?
コンソール出力が UTF8 から変更できない?
Console.OutputEncoding
をみてみると、System.Text.UTF8Encoding となっている。
Windows のコンソールは、 標準では コードページ 932 Shift-JIS になっているので、 UTF8 で出力された文字が文字化けしてしまうのは当然だ。
とりあえずの応急処置として、 出力を Shift-JIS に変更しようとすると…
Console.OutputEncoding = Encoding.GetEncoding(932);
System.NotSupportedException: No data is available for encoding 932. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method. at System.Text.Encoding.GetEncoding(Int32 codepage)
お、おうっ!? 例外が発生するぞ?
どうも、 .NET Core は、標準では Unicode, ASCII, CodePage 28591 (西ヨーロッパ言語) 以外の文字コードをサポートしていないらしい。 (参考: Consoleの文字化け対策 CoreCLR)
日本語などをサポートした System.Text.CodePagesEncodingProvider を利用する必要があるようだ。
ということで、まずは project.json の dependencies に、 System.Text.Encoding.CodePages
を追加しよう。
(dnx や Full .NET Framework には この参照は不要なので、 netcoreapp1.0 にだけ追加しておく。)
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0-rc2-3002702"
}
},
"frameworks": {
"netcoreapp1.0": {
- "imports": "dnxcore50"
+ "imports": "dnxcore50",
+ "dependencies": {
+ "System.Text.Encoding.CodePages": "4.0.1-rc2-24027"
+ }
}
}
}
そして、改めて文字を出力してみる。
using System;
using System.Text;
namespace netcore_console_test_01 {
public class Program {
public static void Main(string[] args) {
Console.WriteLine("はろー わ~るど!");
Console.WriteLine(Console.OutputEncoding);
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Console.OutputEncoding = Encoding.GetEncoding(932);
Console.WriteLine("はろー わ~るど!");
Console.WriteLine(Console.OutputEncoding);
}
}
}
<a href="https://aquasoftware.net/blog/wp-content/uploads/2016/05/160530_2.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2016/05/160530_2.png" alt="160530_2" width="622" height="240" class="alignnone size-full wp-image-899" /></a>
よし、今度はエラーにならずに出力された。
<h2>コンソールの文字コードを自動で選択させる</h2>
しかし、この方法では 強制的に Shift-JIS で出力してしまっているので、 非Windows の環境や 別の言語の環境など、 コンソールが Shift-JIS では逆に文字化けにしてしまう。
できれば、コンソールの文字環境を読んで自動的に文字コードを選択してほしい。
実はなんてことはなく、 <strong>Console クラスのいずれのメソッドも呼ぶ前に、 真っ先に Encoding.RegisterProvider に登録</strong> すれば、その後最初に Console のメソッドで文字コードを解決する際に、自動的に適切な文字コードを選んでくれるのだ。
using System;
using System.Text;
namespace netcore_console_test_01 {
public class Program {
public static void Main(string[] args) {
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Console.WriteLine("はろー わ~るど!");
Console.WriteLine(Console.OutputEncoding);
}
}
}
ただし、 真っ先に というのがポイントで、たとえば Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
の行が実行される前に、 Console.OutputEncoding
のプロパティ値をデバッガーの自動変数などで見てしまうと、 UTF8 で固定されてしまうので注意が必要だ。