Mastodon

酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Windows PhoneでShift-JISやEUC-JPの文字列を扱う

Windows PhoneはUTF-8を使用するのが基本であり、日本で一般的に使われているShift-JIS(以下、SJIS)はサポートされていません。

例えば、SJISを使用しているテキストファイルをダウンロードしてきて文字列を表示させるプログラムを書いてみましょう。

using System;
using System.Net;
using System.Windows;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;

namespace NugetTest {
    public partial class MainPage : PhoneApplicationPage {
        // コンストラクター
        public MainPage() {
            InitializeComponent();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e) {
            // WebClientのインスタンスを生成する
            var client = new WebClient();

            // 文字列のダウンロードを開始する
            client.DownloadStringCompleted += client_DownloadStringCompleted;
            client.DownloadStringAsync(new Uri("http://ch3cooh.jp/files/hello-sjis.txt"));
        }

        // 文字列のダウンロードが完了
        void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) {
            MessageBox.Show(e.Result);
        }
    }
}

このコードを実行すると、SJISの文字列をそのままメッセージボックスで表示させているので、文字化けしてしまっています。


Device Application Development for MVPのtmyt氏(id:tmyt)と@kazuakix氏(http://tauchi.net/)が開発した「JpEncoding」というライブラリを使用することで、SJISやEUC-JPに対応したアプリケーションを作成することが可能です。

「JpEncoding」はNuGetに対応していますので、ライブラリの導入が楽におこなえます。Windows Phone SDK 7.1より「NuGet」と呼ばれる機能を追加することができるようになりました。

ソリューションエクスプローラーの[参照設定]を右クリックしてください。NuGetがインストールされていれば[Manage Nuget Packages...]の項目がありますので選択します。

右上の検索欄に「Japanese」と入力してEnterキーを押下すると、真ん中に検索結果が出てきます。「JpEncoding」を選択すると[Install]ボタンが表示されますのでライブラリを導入します。

先ほどのプログラムの、文字列のダウンロード開始前にWebClientオブジェクトのEncodingプロパティにカスタムエンコーディングを指定します。

using System;
using System.Net;
using System.Windows;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;

namespace NugetTest {
    public partial class MainPage : PhoneApplicationPage {
        // コンストラクター
        public MainPage() {
            InitializeComponent();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e) {
            // WebClientのインスタンスを生成する
            var client = new WebClient();

            // 文字列のダウンロード時に使用するエンコードをSJISに設定する
            client.Encoding = new Japanese.Text.Encoding.SjisEncoding();
            // EUC-JPを使用したい場合
            //client.Encoding = new Japanese.Text.Encoding.EucjpEncoding();

            // 文字列のダウンロードを開始する
            client.DownloadStringCompleted += client_DownloadStringCompleted;
            client.DownloadStringAsync(new Uri("http://ch3cooh.jp/files/hello-sjis.txt"));
        }

        // 文字列のダウンロードが完了
        void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) {
            MessageBox.Show(e.Result);
        }
    }
}

再度実行するときちんと文字が表示されるようになります。


2012/4/1 13:00 追記

NuGetの使い方記事のつもりで書いたのですが、意図に反してJpEncodingの実装方法で賑わってしまいました。皆さんの色々なご意見は、JpEncodingの開発者に伝えておりますので、今後のアップデートがあれば対応して頂けると思います。

もちろん対応が待ちきれないという方はpullして手を入れたり、独自でプロダクトを作るのも良いかと思います。出来ればNuGetで取って来れるように対応して頂ければ嬉しいななんて。

それから、僕が「monoのi18n処理って何?難しいよ」と言っていたら、なんと id:atsushieno さんに「こうするんじゃ、ボケー!」と対応して頂けました。ぐへへっ。

Silverlight for Windows Phoneでの具体的な実装まで示して頂けたので、JpEncodingにコードを盛り込んでも良いかな。

今はサービスリリースしてて、Windows使ってないよっていう状態ですので落ち着いたら続報をまた。