Windows 8

Windows ストア アプリのデバッグ入門

Bruno Terkaly
Robert Evans

1940 年代、グレース・ホッパー中佐はプログラムがうまく機能しないので、実行していたハーバード マーク II のリレー回路を調べたところ蛾がまぎれこんでいるのを見つけました。このことから「バグ」という用語が生まれたと言われています。現在ではもちろん、デバッグという言葉が虫を取り除くことを意味することはなく、ソフトウェアの欠陥を見つけて取り除くことを表します。

事実、現代のプログラミング言語やツールを利用すれば、開発者は堅牢なコードを作成できるようになりますが、ロジックのエラーを防ぐことはできません。現代のコンパイラが行うのは、プログラミング言語構文と型システムの正しい使用に対する基本的なチェックだけで、アプリ実行中の実際の動作をチェックすることはほとんどできません。実行時の動作チェックにはデバッグのスキルが不可欠です。今回は、Windows ストア アプリのデバッグに注目し、その手法をいくつか説明します。

今回は Visual Studio 2013 Preview を使用していますが、ここで説明する手法は以前のバージョンの Visual Studio でもほぼ機能します。ただし、Visual Studio 単独で行えるデバッグよりも高度なデバッグを行うためには、作業を始める前にそれなりの環境を整えておく必要があります。そのため、以下のリソースのダウンロードとインストールをお勧めします。

プロセス ライフサイクル管理

一般的なデスクトップ アプリケーションは、ユーザーが起動してからユーザーが終了するまで実行を継続します。アプリケーションが最前面になくても動作を続けます。Windows ストアのアプリはやや異なり、アプリが最前面からいなくなると、Windows サービス (ランタイム ブローカー) がそのアプリのスレッドをすべて中断します。アプリが最前面に戻った場合のみランタイム ブローカーはすべてのスレッドを再開します。この新機能によりシステム全体のパフォーマンスが向上し、バッテリーが長持ちします。Windows 8.1 の既定の動作では、ユーザーがアプリを閉じた場合も含め、アプリを終了しないで中断状態にします。従来の Windows 8 の動作に戻すには、Windows.ApplicationModel.ClosePolicy.TerminateOnClose を true に設定します。

アプリには中断イベントと再開イベントの両方が送信されるため、状態の保存と取得、また必要であればその他の処理も実行することができます。また、アプリが使用するメモリが多すぎてシステム全体に影響を与えている場合や起動に時間がかかりすぎる場合は、ランタイム ブローカーがそのアプリを終了し、アプリのスレッドをすべて強制終了します。Visual Studio は、デバッグ対象アプリのプロセス ライフサイクル管理 (PLM) を自動的に無効にします。これは自身のアプリをデバックする場合でも、インストールされているアプリをアタッチする場合([デバッグ] の [インストールされているアプリケーション パッケージのデバッグ] を使用) でも同じです。PLM を有効にしておくとアプリを正しくデバッグできなくなるため、PLM を無効にすることは重要です。理由は単純です。アプリを正しくデバッグする機会を得る前に、ランタイム ブローカーが介入して、アプリを終了する可能性があるためです。

ただし、Windows デバッガー (WinDbg) や Microsoft Console Debugger (CDB) など、Visual Studio に組み込まれていない一部のデバッガーでは、PLM 機能を手動で無効にする必要があります。PLM を手動で無効にするには、Windows 8.1 SDK の PLMDebug ツールを使用します。PLMDebug はコマンドライン ツールで、/enableDebug スイッチを使用して特定の .appx パッケージの PLM を無効にできます。特定の .appx のパッケージ ID を特定するには、Windows PowerShell コマンドの Get-AppxPackage、または Process Explorer (後ほど説明) を使用してインストールされているすべてのアプリのパッケージを表示します。

PLMDebug には便利な機能がいくつかあります。たとえば、中断 (Suspend)、再開 (Resume)、終了 (Terminate)、強制終了 (Force-terminate)、中断後終了 (Clean-terminate) などのさまざまなイベントをアプリに明示的に送信できます。また、ライブ デバッガーのアタッチも可能です (この機能については、ここでは取り上げません)。

Visual Studio でも、[デバッグの場所] ツール バーを使用して、中断 (Suspend) イベントおよび再開 (Resume) イベントをトリガーできます。[デバッグの場所] ツール バーは既定では非表示なので、[表示]、[ツール バー]、[デバッグの場所] の順にクリックして表示します。アプリのデバッグに本腰を入れたら、このデバッグ オプションを有効にします。図 1 に Visual Studio 2013 Preview の [デバッグの場所] ツール バーを示します。


図 1 [デバッグの場所] ツール バー

バックグラウンド タスク

ライブ タイルの更新などの多くのシナリオはバックグラウンド タスクを使用しなくても実現できますが、バックグラウンド タスクが必要になるシナリオもあります。バックグラウンド タスクとは、Windows ストア アプリに含まれるコードですが、開発者が定義した特定のシステム状態になると暗黙のうちに開始されるコード部分を表します。たとえば、デバイスが AC 電源に接続されているときのみ、バックグラウンドでアプリのサムネイルを追加または作成するような場合です。メンテナンス トリガーを使用すると、時間間隔とシステム状態を基にタスクをいくつか起動し、反復実行することができます。バックグラウンド タスクのコードはアプリ内で定義しますが、ほとんどの場合 BackgroundTaskHost という別のプロセスによって実行されます。

Windows ストア アプリでは BackgroundTaskBuilder クラスを使用して、自身のバックグラウンド タスクを OS レベルのバックグラウンド インフラストラクチャに登録します。バックグラウンド タスクは、IBackgroundTask インターフェイスを実装するクラスとして作成し、必要なのは Run メソッドを実装することだけです。バックグラウンド タスクには 1 つのトリガーと 1 つ以上の条件の組み合わせを用意します。この組み合わせでバックグラウンド タスクを起動する厳密な状況を表現します。トリガーは BackgroundTaskBuilder クラスの SetTrigger メソッドを使って指定します。

Visual Studio では、[デバッグの場所] ツール バーを使って宣言済みのバックグラウンド タスクを表示して Visual Studio のビジュアル インターフェイスから起動できるので、登録済みのバックグラウンド タスクを見つけてデバッグするのは簡単です。この手法を使えば、あらゆるバックグラウンド タスクを起動できますが、ControlChannelTrigger、PushNotificationTrigger、または SmsReceived 型の SystemTrigger を使用するバックグラウンド タスクは例外です。詳細については、ホワイトペーパー「バックグラウンド タスクの概要」(aka.ms/O35jqc、英語) を参照してください。コード サンプルについては bit.ly/IZpfqN(英語) を参照してください。

アクティブ化

アプリをどのように実装するかによって、File、Protocol、PrintTaskSettings、ShareTarget など、アプリの起動方法が変わります。たとえば、ShareTarget というアクティブ化の種類では、ユーザーが別のアプリから自身のアプリの一部を共有するとアクティブ化されます。

Windows 8.1 ではアクティブ化に関していくつかの変更が加えられています。たとえば、検索によるアクティブ化は非推奨となりましたが、旧バージョンとの互換性のために残っています。また、自身のアプリから他のアプリを起動して、2 つのアプリが画面を共有するという革新的な新手法も取り入れられています。つまり、自身のアプリをアクティブにしたまま、ブラウザーと画面を共有できます。この機能の詳細については、bit.ly/11ckVS3(英語) を参照してください。

上記のいずれかの方法でアクティブ化されるアプリをデバッグするには、まずアプリ プロジェクトのプロパティの [開始動作] を設定します。Visual Studio ソリューション エクスプローラーで [ContosoCookbook] を右クリックし、[プロパティ] をクリックします。[起動しないが、開始時にマイ コードをデバッグする] チェック ボックスをオンにします (図 2参照)。この設定により、あらゆる種類によるアクティブ化でトリガーされる OnLaunched ハンドラーにブレークポイントを設定して、アプリをデバッグできるようになります。また、デバッグ セッションを開始するときに、デバッには備えても実際には起動しないようアプリに指示されるため、アプリは単純に待機状態になります。


図 2 デバッグのプロパティの設定

実行中のアプリの調査

Process Explorer では、実行中のアプリの内部動作を調べるのに便利な機能がいくつか提供されます。ここでは Kids Car Colors というアプリのコードの一部を調査しながら、このような機能を確認します。Kids Car Colors は bit.ly/YnmAxT(英語) でダウンロードできます。スタート画面に移動し、Kids Car Colors アプリを起動後、Process Explorer を起動します (前もって Process Explorer をセットアップしているものとします)。

[svchost.exe] を展開すると、ランタイム ブローカーと、実行中の Windows ストア アプリが表示されます (図 3参照)。[KidsCarColors.exe] を右クリックすると、インストールのルート フォルダーなどのプロパティを表示できます。


図 3 Sysinternals の Process Explorer

アプリのプロパティを示す Process Explorer の画面にはさまざまな情報が表示されます。たとえば、[Image] (イメージ) タブをクリックすると、アプリがインストールされている場所を確認できます (図 4 参照)。組み込みのアプリも Windows ストアからダウンロードしたアプリも、通常、[ルート フォルダー]\Program Files\WindowsApps フォルダーにインストールされます。


図 4 Kids Car Colors アプリのプロパティ

[.NET Performance] (.NET パフォーマンス) タブも便利です。このタブには、ガベージ コレクション (GC) のヒープ サイズ、世代 0 のコレクション数、コレクション実行時間の割合など、基本的なパフォーマンス カウンターの情報が表示されます。これらのパフォーマンス カウンターを確認すると、GC (オブジェクトが参照されなくなったときにメモリを解放するメカニズム) の効果を評価できます。評価の結果によっては、必要なくなったときにメモリを積極的に解放するようにアプリ コードを変更する必要が生じることがあります。.NET パフォーマンス カウンターの詳細については、msdn.microsoft.com/library/w8f5kw2e(英語) を参照してください。

C:\Program Files\WindowsApps フォルダー内のアプリを参照するには、そのフォルダーの所有権とアクセス許可の変更が必要になることがあります。

C:\Program Files\WindowsApps フォルダーには、インストールされているアプリごとにフォルダーがあります。この後説明するように、これらのアプリ フォルダーにはそれぞれ多くの情報が含まれています。

コードの調査

個別のアプリのインストール ディレクトリに移動すると、MP3 ファイル (存在する場合)、画像、XAML ファイル、その他のリソースなど、アプリに関するさまざまな情報が見つかります。ただし、Windows 8.1 アプリの XAML ファイルはバイナリにコンパイルされているので調べることができなくなっています。しかし、C# や Visual Basic .NET で記述された Windows ストア アプリの実行可能ファイルを逆コンパイルできるさまざまなツールがあります。

今回は Telerik の JustDecompile ツールを使用して KidsCarColors.exe を逆コンパイルします。逆コンパイルとはアプリのバイナリを判読可能なソース コードに変換するプロセスです。これを行うには、単純にアプリのインストール フォルダーに移動し、KidsCarColors.exe を右クリックして、[Open with JustDecompile] (JustDecompile で開く) をクリックするだけです。すると、逆コンパイラによって変換されたコード詳細が表示されます (図 5 参照)。アプリ内部のデータ モデルを簡単に判読、参照できます。JustDecompile を使用すると、失われたソース コードを復元したり、外部バグの根本原因を発見するためにアセンブリの詳細を調べたりするのが簡単になります。つまり、インストールされているほぼすべての Windows ストア アプリのソース コードを表示できます。


図 5 KidsCarColors.exe の逆コンパイル

JustDecompile を使用して入手できる情報の量は注目に値します。Kids Car Colors を作成する際、子供が車の色をクリックしたときにオーディオをうまく作動させるのに少し苦労しましたが、そのコードもすべて明らかになります。JustDecompile のプロジェクト エクスプローラーで ItemDetailPage オブジェクトに移動すると、サウンド ファイルがどのように再生されているのか正確にわかります。ローカル ストレージから MP3 を取得し、さまざまなメディア要素のインスタンスを作成し、メディアのコールバック イベントを登録して、SetSource を呼び出しています。すべてのコードが手元に揃い、明らかになるので、だれでもこの手法を再現できます。

JustDecompile のツール バーには、アプリに設定されている参照を調査できる [Assembly List] (アセンブリ一覧) ボタンなど、いくつかのボタンが用意されています。どの参照が Windows ストア アプリに設定されているのかを把握するだけでも、アプリで使用されている機能の内容がわかります。たとえば、Kids Car Colors では Advertising SDK が使用されているのを確認できます。Kids Car Colors には広告が表示されるのでこれには納得がいきます。ただし理論上、自分ではまったく使用していないアセンブリへの参照が設定されている場合もあります。アプリ内の広告は取り除いても、Advertising SDK アセンブリへの参照を取り除くのを忘れた場合を想像してください。JustDecompile を使用すると、実行時に使用されているバージョンや、コードと参照のようすを正確に把握できます。

JustDecompile には Find Usages (使用量の把握) という機能もあります。この機能を使用すると、Visual Studio の [すべての参照の検索] コマンドを再現できます。対応するすべてのコード参照の一覧を取得するには、単純に、逆コンパイル済みコードで、Ctrl キーを押しながら、任意の名前空間、型、またはメンバーをクリックします。この調査は、ソース コードがない場合でも、アプリが機能するしくみについて学習するのに役立ちます。

まとめ

Windows ストア アプリの開発者としての能力を効果を最大限に発揮するには、アプリをデバッグする方法を十分理解しておくことが必要です。今回は、コードの問題点を発見、解決するために使用できるツールと手法をいくつか簡単に見てきました。さらに、ソース コードが手元になくても、Windows ストア アプリが機能するしくみを学習できる有効な手法も紹介しました。

Bruno Terkalyは、マイクロソフトの開発者エバンジェリストです。彼の深い知識は、多数のプラットフォーム、言語、フレームワーク、SDK、ライブラリ、および API を使用してコードを作成し、現場で長年の経験を積むことで得られたものです。コードの作成、ブログ、クラウド ベースのアプリケーション構築 (特に、Windows Azure プラットフォームの使用) に関するライブ プレゼンテーションに携わっています。ブログは、blogs.msdn.com/b/brunoterkaly(英語) で公開されています。

Robert Evans は、プレミア フィールド エンジニアで、Windows 8: Windows Store App Labs のテクニカル リードです。また、マイクロソフト認定プロフェッショナル デベロッパーで、Windows 8 Dev Bootcamp の主任インストラクターでもあります。これまでに、TechReady、GeekReady、および The Tablet Show で講演し、マイクロソフト BUILD カンファレンスの Windows 8 Hardware Lab や多数の Windows 8 ハッカソン イベントを開催してきました。プレミア フィールド エンジニアになる前は、Evans はマイクロソフトのソフトウェア開発エンジニアとして、Xbox Live、MSN、モバイル エンジニアリングなどのさまざまな製品や Microsoft IT での仕事に 12 年間取り組んできました。aka.ms/Utg864(英語) で彼が投稿したプレミア フィールド エンジニアリング ブログを読むことができます。

この記事のレビューに協力してくれた技術スタッフの Christophe Nasarre-Soulier (マイクロソフト) に心より感謝いたします。
Christophe Nasarre はマイクロソフトの開発サポート チームで働いています。1996 年以来、彼は多数の書籍のテクニカル エディターを務め、MSDN マガジン記事もいくつか執筆してきました。