Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
本記事は、マイクロソフト本社の .NET Blog の記事を抄訳したものです。 【元記事】 Universal Windows apps in .NET 2015 2015/07/31 4:55 AM |
今回は、マネージ言語チームでプログラム マネージャーを務める Lucian Wischik による記事をご紹介します。
このたび、Visual Studio 2015 での Windows 10 アプリ開発に使用できるユニバーサル Windows アプリ開発ツールがリリースされました。このリリースにより、最新の .NET テクノロジを使用してユニバーサル Windows プラットフォーム (UWP) アプリを開発することができるようになりました。UWP アプリは、スマートフォン、タブレット、ノート PC、デスクトップ PC、Xbox コンソール、さらには HoloLens (英語)、Surface Hub、Raspberry Pi 2 (英語) といった IoT デバイスなど、Windows ファミリに次々と追加されている最新デバイスを含むあらゆるデバイスで実行することができます。
UWP ツールをインストールする
UWP ツールは、無料のVisual Studio Community Edition をインストールすると既定でインストールされるようになっています。Professional Edition または Enterprise Edition をご利用になる場合は、VisualStudio.com からダウンロードすることができます。セットアップ中に [Custom] を選択して、ユニバーサル Windows アプリ用ツールをインストールします。
既に Visual Studio 2015 をインストールしている場合は、以下のいずれかの方法で入手できます。
- Windows Tools インストーラーをダウンロードして実行します。
- コントロール パネルから [プログラムと機能] を開き、[Visual Studio 2015] を選択して [変更] をクリックします。セットアップ画面で [変更] をクリックし、ユニバーサル Windows アプリ用ツールを選択します。

UWP の最新情報
.NET 開発者の皆様にとっての UWP のメリットは次のとおりです。
- UWP アプリは、Windows 10 にアップグレードされる膨大な数のデスクトップ マシンで実行されます。
- UWP アプリは、スマートフォン、Xbox、HoloLens、さらには Raspberry Pi といった IoT デバイスなど、デスクトップ以外の Windows 10 デバイスでも実行されます。
- UWP アプリは新しい .NET Core (英語) を活用します。最新バージョンの .NET Core では、アプリの開発を容易にする新機能を利用できます。
- .NET においてアプリの中核を成すビジネス ロジックは、ASP.NET 5 などの .NET Core をサポートする他のプラットフォームでも実行できます。
- UWP アプリと共に .NET の小規模なコピーが展開されるため、アプリは必ずテストに使用したバージョンの .NET を使用します。
- UWP アプリが顧客のマシンにダウンロードされる前に、.NET Native によって高度に最適化されたネイティブのマシン コードが生成されます。.NET Native によってアプリの起動時間が大幅に短縮されるほか、バッテリ消費が抑えられ、パフォーマンスが高速化されます。
- UWP アプリは Windows ストアから簡単に購入、インストール、アップグレードすることができます。
- UWP アプリは Application Insights と完全に統合され、詳細なテレメトリと分析を利用できます。Application Insights は、ユーザーを理解し、アプリを改善するために非常に重要なツールです。
また、今回のリリースでは新たに以下のことが可能になりました。
- .NET を使用して Windows 10 UWP アプリを開発できます。
- .NET Core を対象とするポータブル クラス ライブラリを作成できます。
- System.Net.Sockets (英語)、WCF クライアント (英語)、System.Numerics.Vectors (英語)、新しい診断 API (英語) など、これまで Windows ストアや Windows Phone アプリでは使用できなかった .NET の機能を UWP アプリで活用できます。
- NuGet 3.1 (英語) を選択して (project.json ファイルから判別)、あらゆる種類のプロジェクトで NuGet を使用できます。
UWP 開発を始める
UWP 開発に役立つ概要ページとチュートリアルは以下のとおりです。
- Windows 10 ユニバーサル アプリの構築 [MSDN]: ここでは、アダプティブ UI とアダプティブ コードを使用して、あらゆる Windows 10 デバイスで適切に表示され、適切に実行できるアプリの開発方法を説明しています。
- UWP アプリ ガイド (英語) [MSDN]: あらゆるデバイスでユニバーサル アプリがサポートされるしくみについて説明しています。
- アプリを UWP へ移行する [MSDN]: Windows Phone、Silverlight、Windows 8.1、Visual Studio 2015 RC からの移行方法について説明しています。
- C# と XAML によるユニバーサル Windows アプリの開発 (英語) [Microsoft Virtual Academy]: エキスパートの Jerry Nixon による 22 時間の実践的なオンライン トレーニング コースです。
- Visual Studio 2015 で UWP アプリを開発する (英語) [BUILD の講演ビデオ]
- XAML と .NET による UWP 開発の詳細 (英語) [BUILD の講演ビデオ]
ここからは、他のチュートリアルでは扱われていない、.NET 開発者の皆様にとってメリットのある機能強化について主にご説明していきたいと思います。が、その前に、現在 .NET による UWP 開発で利用できる 10 個の機能を画像付きで簡単にご紹介させていただきます。
[File] > [New] > [C#/VB] > [Windows] > [Universal] : 新しい空の UWP アプリを作成します。NuGet が強化されたおかげで、Visual Studio 2015 RC よりも高速に作成できるようになりました。また、UWP、ASP.NET 5、.NET 4.6 を対象とするポータブル クラス ライブラリ (PCL) を作成することもできます。

ソリューションエクスプローラーの [References] : [References] ノードには、NuGet パッケージとそれぞれ特徴的なアイコンが表示されます。ここで注目なのは Microsoft.NETCore.UniversalWindowsPlatform パッケージです。このパッケージには、.NET Core ランタイムと .NET Core Framework が含まれます。packages.config に代わって追加された project.json ファイルにより、新しい NuGet 3.0 を利用できます。NuGet 3.0 は NuGet 2.0 よりも高速で、柔軟性も向上しています。

アダプティブ XAML: デバイスやフォーム ファクターの種類に応じてサイズが変更される「アダプティブ UI」をデザインできます。ViewState トリガー、プレビューに利用できるデバイスの増加、Live Visual XAML Tree によるデバッグなど、多数の XAML 関連の機能強化により、これまでよりもさらに簡単にデザインできるようになりました。また、新しい x:Bind を使用して、高パフォーマンスのデータ バインドを実行できます。

アダプティブコード: 優れたユニバーサル アプリを開発するためには、デバイス間で可能な限り多くのコードを共有すると同時に、デバイスごとに最適なエクスペリエンスを提供できるようにすることが重要です。.NET では、プラットフォーム固有の WinRT API を呼び出して、アダプティブ コードを記述できます。これは、以前に使用されていたリフレクションよりも便利な手法です。

Win2d (英語)とSystem.Numerics.Vectors (英語)による高速なグラフィックス: .NET との親和性が高い洗練された DirectX ラッパー ライブラリである Win2d (英語) を使用して、高速なグラフィックスを実現できます。もちろん、引き続き SharpDX (英語) または MonoGame (英語) を使用することも可能です。また、System.Numerics.Vectors では CPU の SIMD 命令を活用して、ベクトルおよびマトリックスの計算を高速化します。これらすべての機能を利用した結果、筆者が所有するミッドレンジの Nokia 635 でもマンデルブロ フラクタルをわずか 70 ミリ秒で計算することができました。

WCF 、 HTTP/2 、ソケット: これまで Windows Phone アプリでは使用できなかった WCF (英語) と [Add Service Reference] ダイアログが .NET Core ライブラリに追加されました。HttpClient (英語) もゼロから再構築され、パフォーマンスが強化されたほか、HTTP/2 をサポートするようになりました。また、長らくご要望が寄せられていた Windows ストア アプリ向けの .NET 機能 System.Net.Sockets (英語) も追加されました。

デバッグの強化と EnC: エミュレーターでのデバッグ中に「エディット コンティニュ」(EnC) 機能を使用できるようになりました。デバッガー エンジン全体の再設計により、イミディエイト ウィンドウとウォッチ ウィンドウでラムダ式と LINQ 式がサポート (英語) されるようになりました。また、EnC もこれまで以上にさまざまな場所でサポート (英語) されるようになりました。開発者の中には、EnC の実行中にアプリのコードをすべて作成してしまう方もいらっしゃいます。ぜひお試しください!

.NET Native: [Release] モードに設定してビルドを行うと、アプリが新しい .NET Native コンパイラでビルドされます。これにより、高度に最適化されたネイティブのマシンコードに変換され、アプリの起動時間が大幅に短縮されるほか、バッテリ消費が抑えられ、全体的なパフォーマンスが高速化されます。

ストアへの送信: 統合された新しいデベロッパー センターからアプリを送信すると、ウィザードによってアプリの MSIL が送信されます。ストアでは、.NET Native によってコンパイルが行われ、アプリが (C++ コードのようにリバース エンジニアリングが難しい) ネイティブのマシン コードに最適化されてから、ユーザーに展開されます。

Application Insights と Diagnostics: すべての新規プロジェクトには、Application Insights が既定で含まれます。Application Insights では、クラッシュ回数や使用率など、アプリに関する詳細な分析情報が提供されます。分析情報を取得して対応することの重要性は、ストアで上位を占めるアプリの開発者の皆様が理解しているとおりです。また、ETW ではさらに充実したトレース機能 (英語) を利用できます。

.NET Native
.NET Native では、コンパイル時に作成したコードをネイティブのマシン コードに変換する AOT (Ahead-of-Time) コンパイルを採用しています。これとは異なり、従来の .NET では、メソッドの初回実行時までネイティブのコンパイルが実行されない JIT (Just-in-Time) コンパイルが使用されています。.NET Native は C++ コンパイラに近いものです。実際、ツール チェーンの一部には Visual C++ コンパイラが使用されており、アプリの送信時に (エンドユーザーのマシンではなく) Windows ストアで実行されています。.NET Native により、高速で無駄のない自己完結型のコードが生成されます。
.NET Native はエンド ユーザーに多くのメリットをもたらします。アプリの起動時間は最大 60% 短縮され、メモリの使用量も大幅に削減されます。筆者が作成した UWP アプリの中には、Nokia 635 での起動時間を 1 秒から 110 ミリ秒にまで短縮できたものもありました。これは、.NET Native の他に Visual Studio 2015 で新たに追加されたパフォーマンスのヒント機能と診断ツール ウィンドウ (英語) に十分な注意を払った結果です。
.NET チーム ブログには既に .NET Native プレビューに関する多数の記事 (英語) が公開されています。UWP での変更点は、今回初めて .NET Native を「運用環境」で使用できるようになったことです。.NET Native の大部分は透過的に実行されるのに対して、Release ビルドでのビルドはユーザーには確認できません。Release ビルドの方がわずかに処理時間が長く、デバッグ機能がわずかに劣り、パフォーマンス特性もわずかに異なりますが、それ以外の点ではアプリは正常に機能します。CoreCLR を使用する Debug ビルドでは、引き続き期待どおりの優れたデバッグ エクスペリエンスが得られます。
.NET Native のパブリック プレビューは 1 年以上継続していましたが、多くの皆様にとって UWP の使用は今回が初めてになります。そのため、UWP のしくみについてさらに詳しくご説明したいと思います。私たちがこの製品にいかに誇りを持っているかをお伝えすると同時に、皆様にとって関心の高い情報をご提供できれば幸いです。
.NET Core Framework
.NET Core (英語) Framework (CoreFX) については、先日こちらのブログ記事でも取り上げました。
.NET Core は、最新のデバイスとクラウド ワークロードに対応した新しいバージョンの .NET です。汎用かつモジュール型の実装であるため、さまざまな環境に移植して、多様なワークロードに使用することができます。
CoreFX は UWP アプリに使用されており、Windows ストア アプリの開発に使用することのできた .NET API のスーパーセットです。
UWP 開発者の皆様が特に関心を抱かれる .NET Core FX の特徴について、以下にまとめました。
- これまで System.Net.Sockets (英語) (UDP 通信に使用) を WinRT アプリで使用することはできず、回避策として WinRT 固有の UDP API を使用していました。今回 System.Net.Sockets が .NET Core に含まれるようになったため、すべての UWP アプリで使用することができます。さらに、ソケット コードを他の .NET アプリと共有することもできます (メモ: 現在 System.Net.Sockets のオープン ソース化を進めています)。
- (.NET Core FX の下位部分の大半と同様に) HttpClient (英語) は実行するプラットフォームごとに異なる実装が必要です。UWP アプリでは、WinRT HTTP スタックの上位に構築されているため、サーバーがサポートする場合は HTTP/2 を既定で使用することが可能で、待機時間が短縮されると共にラウンド トリップ通信の回数も減少します。
- これまで WCF クライアント (英語) (および関連する [Add Service Reference] ダイアログ) を Windows Phone の appx プロジェクトで使用することはできませんでした。しかし、.NET Core に含まれるようになったため、すべての UWP アプリで使用することが可能になりました。
- System.Numerics.Vectors (英語) により、CPU の SIMD (Single Instruction Multiple Data) オペコードで実装されるベクトル型およびマトリックス型を使用できます。これは通常の SISD (Single Instruction Single Data) オペコードよりも高速にベクトルやマトリックスを処理できます。また、-System.Diagnostics.Tracing.EventSource を使用して、イベントの Windows イベント トレーシング (ETW) にさらにリッチなペイロード (英語) を送信できるようになりました。
CoreFX の魅力的な点は、オープン ソース (英語) であることと、Windows および Visual Studio のメジャー リリースから独立していることです。どなたでも参加することが可能で、.NET チームも日常的に参加しています。現在、.NET チームとコミュニティは CoreFX を拡張してさらに多くの API を追加すべく取り組んでいます。追加された API は UWP アプリで使用できるようになります。project.json と NuGet の登場により、UWP 開発者の皆様は最新の .NET Core FX パッケージがリリースされしだい、[Manage NuGet Packages] ダイアログをクリックしてすぐに利用することができるようになります。
[File]、[New] の順に選択すると、UWP アプリに関連のあるテスト済みの正式な Microsoft .NET Core アセンブリの完全なセットを利用できます。マイクロソフトのその他のライブラリや将来的にリリースされるライブラリを追加する場合は、[References] > [Add References] ではなく、[References] > [Manage NuGet References] を選択してください。
また、.NET Core ライブラリを作成する場合は、.NET 4.6、UWP、ASP.NET 5 を対象とする PCL を作成できます。
ユニバーサル プロジェクト
UWP の登場によって、「ユニバーサル」なアプリの作成が可能になります。つまり、Visual Studio の 1 つのプロジェクト、1 つのコードベース、Windows デベロッパー センターへの 1 回のアップロードで、デスクトップ、モバイル、Xbox などの複数の「デバイス ファミリ」で実行できるアプリを完成させることができます。UWP なら、コードに #ifdef を使用したり、共有プロジェクトを利用したりする必要はないため、アプリの開発や保守が容易になります。
MSDN の「UWP アプリ ガイド (英語)」では、どのデバイスでもアプリを適切に表示できるようにするための方法についてわかりやすく説明しています。アプリをさまざまな画面サイズのデスクトップで適切に表示するためには UI の調整が必要でしたが、この方法は、異なるデバイスでアプリを適切に表示するためにも必要です。
.NET の観点から言うと、技術的に最も興味深いのがアダプティブ コードです。次に例を示します。

作成したアプリは Windows 10 のデスクトップ PC では適切に表示されていましたが、Windows 10 のモバイル デバイスではステータス バーが表示されていました。StatusBar.HideAsync を呼び出した方が見栄えが良くなると考えていましたが、StatusBar という型 (および概念) はデスクトップにすら存在しません。この存在しない型に対処するコードは単純です。WinRT API の Windows.Foundation.Metadata.ApiInformation.IsTypePresent を使用すると、アプリが実行されているマシンに指定した WinRT 型が存在するかどうかを判断し、存在する場合にのみプラットフォーム固有のメソッドを呼び出します。
しかし、呼び出した API に対して IsTypePresent を指定する必要があるかどうかを逐一覚えていられない場合もあります。そのようなときのために、PlatformSpecific.Analyzer (英語) という NuGet パッケージを作成しました。このパッケージをプロジェクトに追加すると、IsTypePresent を指定しなければならない場合に IDE に波線による警告が表示されます。
このようなスタイルのアダプティブ コードは、.NET では現在 UWP プラットフォームで UWP 型を使用した場合にのみ作成できます。下位の .NET に精通している方のために詳細をご説明しましょう。Debug ビルドの場合、CoreCLR が SetupAsync メソッドの JIT コンパイルを実行できるようにする必要があります。そのためには、実行時に一度も選択されない分岐を含め、本文に含まれるすべての型とメソッドのメタデータを把握する必要があります。UWP では、これに対処するために「windows.winmd」というアプリのローカル ファイルをバンドルします。このファイルには、すべての UWP デバイス ファミリおよびバージョンに対応する WinRT のすべての型とメソッドのメタデータが含まれます。Release ビルドの場合は、.NET Native のコンパイルによって必要なメタデータが COM IID および vtable の形式で最終的なネイティブのマシン コードに追加されます。
最後に、アダプティブ アプリの PCL についてもう 1 点言及したいと思います。これは、既存のコードベースを UWP に移植するために重要な点です。Windows 8.1 と Windows Phone 8.1 の両方を対象とする「8.1 ユニバーサル PCL」を作成した場合は、UWP アプリから参照することが可能で、通常は問題なく機能します。それは、これらの PCL は WinRT API のサブセットにのみ呼び出すことが可能であり、このサブセットがすべての UWP プラットフォームでサポートされているためです。
NuGet 3.0 と「 project.json 」
NuGet は .NET アプリにおけるパッケージ管理のデファクト スタンダードになりつつあります。.NET Core を NuGet パッケージとして展開しようとした際、.NET Core を構成する 100 以上のサブパッケージに合わせて拡張するには、NuGet 2.0 クライアントと packages.config は (対応するシナリオには優れた効果を発揮するものの) スピードも柔軟性も不十分で、最適な選択肢とは言えませんでした (英語)。NuGet 3.0 (英語) ではこの問題が解決されており、ASP.NET 5 で初めて使用されたほか、今回 UWP にも使用されています。
プロジェクトが NuGet 3.0 を使用しているかを判別するには、packages.config の代わりに project.json ファイルが含まれていることを確認します。また、既存の .NET プロジェクトに project.json を追加しても同様に動作します (最初にプロジェクトをアンロードしてからロードする必要があります)。project.json が動作するしくみは以下のとおりです。
- NuGet パッケージをインストールすると、project.json ファイルに参照が追加され、ソリューション エクスプローラーの [References] ノードに表示されます。
- ビルドの実行前に、マシンのユーザー別のキャッシュにすべての NuGet パッケージ (依存関係を含む) がダウンロードされていることが Visual Studio によって確認され、プロジェクトの現在のターゲットまたはアーキテクチャに応じて使用するパッケージが選択されます (メモ: この操作を Visual Studio 以外で実行できるように、間もなくスタンドアロンの「nuget.exe」コマンドライン ツールがリリースされる予定です)。
- project.json ファイルが存在する場合、ビルド時に MSBuild がこのファイルを読み取り、ファイルに含まれている適切な DLL と .targets ファイルを参照します。
project.json を使用したワークフローのメリットは以下のとおりです。
- .vbproj/.csproj ファイルに NuGet への参照が含まれず、完全に別々に保存されるようになります。このため、ソース管理やマージの競合解決を簡単に実行することができます。
- アプリのターゲット プラットフォームを変更したり、Debug/Release や x86/x64/ARM/Any CPU を切り替えたりした場合、NuGet でそれらの設定を使用するようになります。
- 異なる 2 つのディレクトリに異なる 2 つのソリューションを作成し、それぞれに同じ NuGet を使用するプロジェクトを含めることができるようになります。これは、異なる 2 つのリポジトリ間で作業している場合に特に便利です。
- ソリューション エクスプローラーの [References] ノードには、インストール時に実際に選択したパッケージのみが表示され、依存関係は表示されなくなるため、表示がシンプルになります。同様に、NuGet パッケージをアンインストールする場合にも、すべての依存関係を含めるのではなく、インストール時に選択したパッケージをアンインストールするだけでよくなります。
- パッケージはグローバル (ユーザー別、マシン別) にキャッシュされるため、ソリューションでパッケージを使用するたびにローカルでダウンロードして解凍する必要がなくなります。
- [File] > [New] および [Manage NuGet Packages] > [Install] の処理が高速になります。
- NuGet パッケージのアップグレードやバージョンの不一致をより詳細に制御できるようになります。
NuGet の詳細については、NuGet チーム ブログ (英語) および NuGet の Home リポジトリ (英語) をご覧ください。いずれも、NuGet に関する変更点を NuGet チームと確認するために最適です。既知の問題については、今後の更新で次のような対応を検討しています。ASP.NET 5 の場合と同様に、ソリューション エクスプローラーの [References] ノードに UWP アプリに含まれる NuGet パッケージの一時的な依存関係がすべて表示されるようにします。この点について、皆様のご意見をお聞かせいただければ幸いです。
一部の NuGet パッケージは UWP アプリにインストールされた場合の動作が少々異なります。以下に挙げたもの以外にお気付きになったり、一部のアプリでブロックされたりする場合は、この記事の下部にあるコメント欄からお知らせください。
- SharpDX.Toolkit 2.6.3: SharpDX 3 (英語) (現時点ではアルファ版) にアップグレードされ、UWP アプリで正常に動作します。SharpDX Toolkit は廃止され、バージョン 3 に移行したり、UWP アプリにインストールしたりすることはできません。代替案として、Paradox (英語) や MonoGame (英語) など、SharpDX を基盤として構築された他のツールキットの使用を検討してください。
- MvvmLight: この NuGet パッケージは UWP アプリで正常に動作しますが、そのためにはインストール時に追加の手順を実行する必要があります。本来インストール時には、App.xaml ファイルが修正され、その他にいくつかのファイルがプロジェクトに追加されますが、UWP アプリの場合にはこの処理が実行されなくなったため、手動で変更するか、代わりに MvvmLight VSIX (英語) を使用する必要があります。
- Sqlite-net: この NuGet パッケージを UWP アプリにインストールすることはできなくなりましたが、(同じ作成者による) 同等の Sqlite.Net-PCL (英語) は正常に動作します。
- LiveSDK: この NuGet パッケージは正常にインストールされたと表示されますが、実際には DLL の参照に失敗します。短期的な回避策としては、Microsoft.Live.dll への参照を手動で追加します (この DLL の保存場所を確認するためには、UWP アプリに LiveSDK への参照を追加してから、%USERPROFILE%.nuget\packages\LiveSDK にあるダウンロードした NuGet パッケージを指定する方法が最も簡単です)。代替案として、サインインにはこちらのページ (英語) に記載されている手順に従って Windows.Security.Authentication.OnlineID を使用し、OneDrive には HttpClient から REST API (英語) を使用することもできます。
偶然にも、project.json は「モダン」PCL、つまりターゲットが .NET 4.6、UWP、ASP.NET 5 Core のいずれかまたはすべてに限定されている PCL にも既定で使用されています。
UWP アプリ : Debug ビルドには CoreCLR 、 Release ビルドには .NET Native を使用
以下の図は、UWP アプリをビルドし、デバッグして、ストアに送信した際の処理を示しています。VB および C# コンパイラによって MSIL 形式の DLL が生成される点は以前と同様ですが、その後の処理が変更になりました。

Debug ビルドでは CoreCLR を使用: UWP アプリを Debug モードでビルドする場合、ASP.NET 5 で使用されているのと同じ「.NET CoreCLR」ランタイムが使用されます。これにより、高速な展開、充実したデバッグ機能、エディットコンティニュ機能を利用できるようになり、編集、実行、デバッグのエクスペリエンスが向上します。
Release ビルドでは .NET Native を使用: Release モードでビルドする場合、MSIL と参照を最適化されたネイティブのマシン コードに変換するためにさらに 30 秒以上の時間がかかります。この時間を短縮するために、さまざまな取り組みを行っています。一度も呼び出されないコードをすべて削除 (tree-shaking) するほか、「マーシャリング コードの生成 (英語)」によってシリアル化コードをプリコンパイルすることで実行時のリフレクションを回避したり、プログラム全体の最適化を行ったりします。ネイティブコードに対するこれらの処理とコンパイルによって、単一のネイティブ DLL が生成されます。このファイルは bin\x86\Release\ilc に保存されます。
**.NET Core: CoreCLR と .NET Native はいずれも「.NET コア ランタイム」です。どちらも同じ .NET Core ライブラリ (CoreFX) を使用できるため、Debug と Release で同じエクスペリエンスが得られます。Windows 8/8.1 では、Windows ストアアプリの基盤となる .NET 実装として .NET Framework が使用されていました。Windows 10 では、デバッグとリリースのエクスペリエンスを向上すると共に、新しい CoreFX ライブラリにアクセスできるように、.NET Core を使用するように完全に移行しました。
ストアへの送信: Windows ストアに送信するために appx パッケージを作成した場合、appx バンドルには MSIL が含まれます。その後、Windows ストアで .NET Native によるコンパイルが実行されます。これにより、.NET Core FX をアプリのローカルに展開した場合に、.NET でセキュリティの脆弱性が検出されたときの懸念を低減することができます。従来は .NET の全 OS のバージョンに Windows Update をリリースして解決していましたが、今後は脆弱性のある appx パッケージを特定し、作成者と共に修正することで解決できます。
.NET Native による開発のヒント
Release ビルドでのアプリのテスト: 開発中には Release ビルドで UWP アプリを定期的にテストするようにしてください。Release ビルドでは .NET Native を使用しています。定期的にテストすれば (筆者の場合、開発時には 4 時間程度の間隔で実施しています)、Expression.Compile のパフォーマンスの違いなどの問題を迅速に発見することができます。テスト中に問題を発見し、デバッグが必要になる場合は、Release ビルドは完全に最適化されており、最良のデバッグ結果を得るためには最適化を無効にする必要がある (英語) という点に注意してください。
.NET Native Analyzer: 5 次元以上の多次元配列など、.NET の機能には .NET Native でサポートされていないものが数点あります。機能がサポートされていない場合は、.NET Native でのビルド時にメッセージが表示されますが、.NET Native でのビルドにかかる 30 秒以上の時間を無駄にしないためには、NuGet パッケージの Microsoft.NETNative.Analyzer (英語) への参照を追加すれば、入力した直後に警告が表示されるようになります。
Any CPU の利用を中止: Any CPU の利用が中止になります。これは、.NET Native ではネイティブのマシン コードにコンパイルされるためです。アプリ開発の場合は、特に影響はありません。ローカル マシンまたはエミュレーターに展開する場合は [x86]、Windows 10 のモバイル デバイスに展開する場合は [ARM]、あるいは [x64] (このオプションには x86 と比較して大したメリットがありません) のいずれかを選択すれば問題ありません。また、ストア用の appx パッケージを作成した場合は、ウィザードによって 3 種類すべてのビルドが作成され、アプリ バンドルとしてストアに送信されます。
しかし、クラス ライブラリ (PCL) を作成する場合は、通常「Any CPU」として作成する必要があります。これにより、単一の DLL を配布して、あらゆる種類のプロジェクトで簡単に利用することができます。
個人的には、[Build] メニューから [Configuration Manager] ダイアログを使用する方法が最も簡単だと思います。設定を行えば、ツールバーに表示されたライブラリの対象が「Any CPU」である場合にも、UWP アプリを x86 としてビルドおよび展開することができます。

.NET Native のデバッグ: 場合によっては、.NET Native でブレークポイントを設定し、コードのデバッグを行う必要があります。その際には、Release ビルドで実行しないことをお勧めします。Release ビルドではもともとデバッグが難しいうえに、.NET Native によるアグレッシブな最適化によってさらに困難になるためです。この問題を解決するためには、Debug モードを使用して (最適化を無効化し)、Debug ビルドでも .NET Native を使用するようにプロジェクトの構成を一時的に変更します。C# の場合は、[Project] > [Properties] > [Compile with the .NET Native tool chain]、VB の場合は、[My Project] > [Build] > [Advanced] から設定できます。
.NET Native による最適化のカスタマイズ: 特にアプリでリフレクションをほとんど使用しない場合などは、.NET Native による最適化でコードが必要以上に削除されることがあります。これを制御する方法については、以下のブログ記事をご覧ください。
- 静的コードの動的な機能 (英語)
- MissingMetadataException が発生した場合の対処法 (英語)
- MissingMetadataException が発生しなかった場合の対処法 (英語)
- .NET Native の詳細: 優れたライブラリの作成方法 (英語)
- .NET Native の詳細: ランタイム ディレクティブによる最適化 (英語)
*Expression.Compile: Newtonsoft の Json.Net で内部的に使用されており、多数の開発者の皆様に影響するため、注意が必要です。従来の CLR では、実行時に式ツリーを MSIL にコンパイルし、その後 JIT コンパイルによってネイティブ コードに変換することができます。.NET Native ではこの処理を実行することができず、代わりに式ツリーを「解釈」します。Json.Net では、起動が大幅に高速化されるものの (CLR の式ツリーインフラストラクチャを読み込む必要がなくなったため)、サイズの大きなデータ ファイルのシリアル化にこれまでよりも時間がかかるなどの変化が見られる可能性があります。作成したアプリでこの変更が重要であるかどうかを測定してください。筆者の場合は、アプリの起動時間が約 200 ミリ秒短縮されました。
F# : 現時点では、F# の DLL は .NET Native によってサポートされていないため、UWP ストア アプリで使用できません。このシナリオについては、今後の修正を検討しています。皆様にとって重要かどうか、ぜひご意見をお聞かせください!
サポートが必要な場合: .NET Native に関する問題が発生し、サポートが必要な場合は、dotnetnative@microsoft.com までご連絡ください。
まとめ
今回のユニバーサル Windows プラットフォームのリリースにより、.NET 開発者の皆様にとって新たなチャンスが広がることになります。開発した UWP アプリを膨大な数のユーザーに提供できるだけでなく、最先端の .NET テクノロジを使用してコードを作成できるようになります。
ぜひお試しいただき、ご意見をお聞かせください。ご不明な点がある場合は、この記事のコメント欄または Windows デベロッパー センターの「ユニバーサル アプリ開発 (英語)」フォーラムまでご質問をお寄せください。また、アプリの起動時間を測定し、.NET Native によって 200 ミリ秒以下にまで短縮できた場合は、その件についてもぜひコメント欄にご投稿ください!