WPF アプリケーション (WPF) のビルド

更新 : 2010 年 11 月

Windows Presentation Foundation (WPF) アプリケーションは、.NET Framework の実行可能ファイル (.exe)、ライブラリ (.dll)、またはこれらの両方のタイプのアセンブリの組み合わせとしてビルドできます。 このトピックでは、WPF アプリケーションをビルドする方法を紹介し、ビルド処理の主要な手順について説明します。

このトピックは、次のセクションで構成されています。

  • WPF アプリケーションのビルド
  • WPF ビルド パイプライン
  • インクリメンタル ビルドのサポート
  • 関連トピック

WPF アプリケーションのビルド

WPF アプリケーションは、次の方法でコンパイルできます。

  • コマンド ライン。 アプリケーションにはコード (XAML ではない) とアプリケーション定義ファイルだけを含める必要があります。 詳細については、「csc.exe を使用したコマンド ラインからのビルド」または「コマンド ラインからのビルド (Visual Basic)」を参照してください。

  • Microsoft Build Engine (MSBuild)。 コードおよび XAML ファイルに加えて、アプリケーションには MSBuild プロジェクト ファイルを含める必要があります。 詳細については、「MSBuild」を参照してください。

  • Visual Studio Visual Studio は、WPF アプリケーションと MSBuild をコンパイルし、UI を作成するためのビジュアル デザイナーを含む、統合開発環境です。 詳細については、「Visual Studio でのアプリケーション開発」および「WPF デザイナー」を参照してください。

WPF ビルド パイプライン

WPF プロジェクトがビルドされると、言語固有のターゲットと WPF 固有のターゲットの組み合わせが呼び出されます。 これらのターゲットを実行するプロセスをビルド パイプラインと呼びます。主要な手順を次の図に示します。

WPF ビルド処理

ビルド前の初期化

ビルドを実行する前に、MSBuild は、次のような主要なツールおよびライブラリの場所を確認します。

  • .NET Framework。

  • Windows SDK ディレクトリ。

  • WPF 参照アセンブリの場所。

  • アセンブリ検索パスのプロパティ。

MSBuild がアセンブリを最初に検索する場所は、参照アセンブリ ディレクトリ (%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.0\) です。 また、この手順では、ビルド プロセスがさまざまなプロパティおよび項目のグループを初期化し、必要なクリーンアップ作業を実行します。

参照の解決

ビルド プロセスは、アプリケーション プロジェクトのビルドに必要なアセンブリを探してバインディングします。 このロジックは、ResolveAssemblyReference タスクに含まれます。 プロジェクト ファイル内で Reference として宣言されたすべてのアセンブリは、検索パスに関する情報と、既にシステムにインストールされているアセンブリのメタデータと共にタスクに渡されます。 タスクはアセンブリを検索し、インストールされているアセンブリのメタデータを使用して、出力マニフェストに含める必要のないコアの WPF アセンブリをフィルターして除外します。 これは、ClickOnce マニフェストで情報が重複するのを避けるために行われます。 たとえば、PresentationFramework.dll は WPF でビルドされた代表的なアプリケーションと見なすことができ、また、すべての WPF アセンブリは .NET Framework がインストールされているすべてのコンピューターで同じ場所に存在するため、マニフェストにすべての .NET Framework 参照アセンブリに関するすべての情報を含める必要はありません。

マークアップ コンパイルのパス 1

この手順では、XAML ファイルを解析してコンパイルし、ランタイムが XML の解析やプロパティ値の検証などに時間を費やさずに済むようにします。 コンパイル済みの XAML ファイルを事前にトークン化するため、実行時の読み込みは XAML ファイルを読み込むよりもはるかに短時間で終わります。

この手順では、Page ビルド項目である XAML ファイルごとに次のアクティビティが実行されます。

  1. XAML ファイルがマークアップ コンパイラによって解析されます。

  2. 対象の XAML に対してコンパイル済みの形式が作成され、obj\Release フォルダーにコピーされます。

  3. 新しい部分クラスの CodeDOM 形式が作成され、obj\Release フォルダーにコピーされます。

さらに、言語固有のコード ファイルが XAML ファイルごとに生成されます。たとえば、Visual Basic プロジェクトの Page1.xaml ページに対して Page1.g.vb が生成され、C# プロジェクトの Page1.xaml ページに対して Page1.g.cs が生成されます。 ファイル名に含まれる ".g" は、ファイルが生成されたコードであり、マークアップ ファイルのトップレベルの要素 (Page、Window など) に対する部分クラス宣言を持つことを示しています。 クラスは C# でpartial修飾子 (Visual Basic では Extends) を指定して宣言され、他の場所に別のクラス宣言があることを示します。通常は分離コード ファイル Page1.xaml.cs 内です。

部分クラスは該当の基本クラスから拡張され (ページの Page など)、System.Windows.Markup.IComponentConnector インターフェイスを実装します。 IComponentConnector インターフェイスには、コンポーネントを初期化し、コンテンツ内の要素の名前とイベントを結び付けるメソッドがあります。 そのため、生成されたコード ファイルには次のようなメソッド実装が含まれます。

public void InitializeComponent() {
    if (_contentLoaded) {
        return;
    }
    _contentLoaded = true;
    System.Uri resourceLocater = 
        new System.Uri(
            "window1.xaml", 
            System.UriKind.RelativeOrAbsolute);
    System.Windows.Application.LoadComponent(this, resourceLocater);
}
Public Sub InitializeComponent() _

    If _contentLoaded Then
        Return
    End If

    _contentLoaded = True
    Dim resourceLocater As System.Uri = _
        New System.Uri("mainwindow.xaml", System.UriKind.Relative)

    System.Windows.Application.LoadComponent(Me, resourceLocater)

End Sub

既定で、マークアップ コンパイルは MSBuild エンジンと同じ AppDomain 内で実行されます。 これにより、パフォーマンスが大幅に向上します。 この動作は、AlwaysCompileMarkupFilesInSeparateDomain プロパティで切り替えられます。 切り替えた場合、別の AppDomain をアンロードすることにより、すべての参照アセンブリをアンロードするという利点があります

マークアップ コンパイルのパス 2

マークアップ コンパイルのパス 1 ですべての XAML ページがコンパイルされるとは限りません。 ローカルで定義された型参照 (つまり、同じプロジェクト内の他のコードで定義された型の参照) を含む XAML ファイルは、この時点ではコンパイルから除外されます。 これは、ローカルで定義された型はソース内にのみ存在し、まだコンパイルされていないためです。 これを判別するために、パーサーはマークアップ ファイル内で x:Name などの項目を検索するヒューリスティックを使用します。 このようなインスタンスが見つかると、そのマークアップ ファイルのコンパイルはコード ファイルがコンパイルされるまで延期されます。その後、2 回目のマークアップ コンパイル パスでこれらのファイルが処理されます。

ファイルの分類

ビルド プロセスにより、配置するアプリケーション アセンブリに基づいて、出力ファイルが別のリソース グループに配置されます。 通常、ローカライズされないアプリケーションでは、Resource とマークされたすべてのデータ ファイルはメイン アセンブリ (実行可能ファイルまたはライブラリ) に配置されます。 UICulture がプロジェクト内に設定されると、コンパイル済みのすべての XAML ファイルおよび言語固有と明示的にマークされたリソースは、サテライト リソース アセンブリに配置されます。 また、言語に依存しないすべてのリソースは、メイン アセンブリに配置されます。 ビルド プロセスのこの手順で、この決定が行われます。

プロジェクト ファイル内の ApplicationDefinition、Page、および Resource ビルド アクションは、Localizable メタデータで拡張できます (入力可能値は true および false)。これにより、ファイルが言語固有か、言語に依存しないかを指定します。

コア コンパイル

コア コンパイルの手順では、コード ファイルをコンパイルします。 これは、Microsoft.CSharp.targets や Microsoft.VisualBasic.targets など、言語固有のターゲット ファイル内のロジックによって調整されます。 ヒューリスティックによってマークアップ コンパイラの 1 回のパスでは不十分であることが判断されると、メイン アセンブリが生成されます。 ただし、プロジェクト内の 1 つ以上の XAML ファイルにローカルで定義された型の参照が含まれている場合は、一時的な .dll ファイルが生成されます。これにより、マークアップ コンパイルの 2 回目のパスが完了すると、最終的なアプリケーション アセンブリが作成されます。

マニフェストの生成

ビルド プロセスの終わりに、すべてのアプリケーション アセンブリとコンテンツ ファイルの準備が整った後で、アプリケーションの ClickOnce マニフェストが生成されます。

配置マニフェスト ファイルには、配置モデル (現在のバージョン、更新動作、および発行元の ID とデジタル署名) が記述されています。 このマニフェストは、配置を処理する管理者が作成します。 ファイル拡張子は、XAML browser applications (XBAPs) を表す .xbap とインストール型のアプリケーションを表す .application です。 前者は HostInBrowser プロジェクト プロパティによって指定されるため、マニフェストはアプリケーションがブラウザーによってホストされることを識別します。

アプリケーション マニフェスト (.exe.manifest ファイル) には、アプリケーション アセンブリ、依存ライブラリ、およびアプリケーションで必要なアクセス許可のリストが記述されています。 このファイルは、アプリケーション開発者が作成します。 ClickOnce アプリケーションを起動するには、ユーザーはアプリケーションの配置マニフェスト ファイルを開きます。

これらのマニフェスト ファイルは、常に XBAPs 用に作成されています。 インストール型のアプリケーションでは、プロジェクト ファイル内で GenerateManifests プロパティ値を true に指定しない限り作成されません。

XBAPs は、一般的なインターネット ゾーン アプリケーションに割り当てられるこれらの許可のほかに、2 つの追加の許可を取得します。追加の許可とは、WebBrowserPermissionMediaPermission です。 WPF のビルド システムは、アプリケーション マニフェストでこれらのアクセス許可を宣言します。

インクリメンタル ビルドのサポート

WPF のビルド システムは、インクリメンタル ビルドをサポートします。 これは、マークアップやコードの変更を検出し、変更の影響を受けるアイテムだけをコンパイルするという高度な機能です。 インクリメンタル ビルド メカニズムでは、次のファイルを使用します。

  • $(AssemblyName)_MarkupCompiler.Cache ファイル。現在のコンパイラの状態を保持します。

  • $(AssemblyName)_MarkupCompiler.lref ファイル。ローカルで定義された型への参照を持つ XAML ファイルをキャッシュします。

インクリメンタル ビルドの規則を次に示します。

  • ビルド システムが変更を検出できるのは、ファイル単位以上です。 そのため、コード ファイルの場合、ビルド システムは型が変更されたかどうか、またはコードが追加されたかどうかを通知できません。 同じことはプロジェクト ファイルにも当てはまります。

  • インクリメンタル ビルドのメカニズムは、XAML ページがクラスを定義するのか、他のクラスを使用するのかを認識していなければなりません。

  • Reference のエントリが変更された場合は、すべてのページを再コンパイルします。

  • コード ファイルが変更された場合は、ローカルで定義された型参照を含むすべてのページを再コンパイルします。

  • XAML ファイルが変更された場合 :

    • XAML がプロジェクトで Page として宣言されている場合 : XAML にローカルで定義された型参照がなければ、その XAML とローカル参照を含むすべての XAML ページを再コンパイルします。XAML にローカル参照があれば、ローカル参照を含むすべての XAML ページを再コンパイルします。

    • XAML がプロジェクト内で ApplicationDefinition として宣言されている場合 : すべての XAML ページを再コンパイルします (それぞれの XAML に、変更された可能性のある Application 型への参照があるため)。

  • プロジェクト ファイルで、XAML ファイルではなくコード ファイルをアプリケーション定義として宣言している場合 :

    • プロジェクト ファイル内の ApplicationClassName 値が変更されたかどうかを確認します (たとえば、新しいアプリケーションの種類があるかどうか)。 その場合は、アプリケーション全体を再コンパイルします。

    • または、ローカル参照を含むすべての XAML ページを再コンパイルします。

  • プロジェクト ファイルが変更された場合は、上記のすべての規則を適用し、再コンパイルする必要があるものを確認します。 次のプロパティが変更されると、全体の再コンパイルが実行されます : AssemblyName、IntermediateOutputPath、RootNamespace、および HostInBrowser。

次の再コンパイルのシナリオが考えられます。

  • アプリケーション全体が再コンパイルされます。

  • ローカルで定義された型参照を含む XAML ファイルだけが再コンパイルされます。

  • 再コンパイルされるものはありません (プロジェクト内で変更が加えられていない場合)。

参照

概念

WPF アプリケーションの配置 (WPF)

WPF におけるパッケージの URI

WPF アプリケーションのリソース ファイル、コンテンツ ファイル、およびデータ ファイル

その他の技術情報

WPF MSBuild のリファレンス

履歴の変更

日付

履歴

理由

2010 年 11 月

Visual Basic の例を補足。

コンテンツ バグ修正