次の方法で共有


アプリケーション管理の概要

すべてのアプリケーションは、アプリケーションの実装と管理に適用される共通の機能セットを共有する傾向があります。 このトピックでは、アプリケーションを作成および管理するための Application クラスの機能の概要について説明します。

アプリケーションクラス

WPF では、アプリケーション スコープの一般的な機能が Application クラスにカプセル化されます。 Application クラスには、次の機能が含まれています。

  • アプリケーションのライフサイクルの追跡と管理。

  • コマンド ライン パラメーターの取得と処理。

  • ハンドルされない例外を検出して応答する。

  • アプリケーション スコープのプロパティとリソースの共有。

  • スタンドアロン アプリケーションでのウィンドウの管理。

  • ナビゲーションの追跡と管理。

アプリケーション クラスを使用して一般的なタスクを実行する方法

Application クラスのすべての詳細に関心がない場合は、次の表に、Applicationの一般的なタスクとその実行方法を示します。 関連する API とトピックを表示すると、詳細情報とサンプル コードを見つけることができます。

課題 方法
現在のアプリケーションを表すオブジェクトを取得する Application.Current プロパティを使用します。
アプリケーションにスタートアップ画面を追加する WPF アプリケーションへのスプラッシュスクリーンの追加を参照してください。
アプリケーションを起動する Application.Run メソッドを使用します。
アプリケーションを停止する Shutdown オブジェクトの Application.Current メソッドを使用します。
コマンド ラインから引数を取得する Application.Startup イベントを処理し、StartupEventArgs.Args プロパティを使用します。 例については、 Application.Startup イベントを参照してください。
アプリケーション終了コードを取得して設定する ExitEventArgs.ApplicationExitCode イベント ハンドラーで Application.Exit プロパティを設定するか、Shutdown メソッドを呼び出して整数を渡します。
ハンドルされない例外を検出して応答する DispatcherUnhandledException イベントを処理します。
アプリケーション スコープのリソースを取得して設定する Application.Resources プロパティを使用します。
アプリケーション スコープのリソース ディクショナリを使用する 「Application-Scope リソース ディクショナリの使用」を参照してください。
アプリケーション スコープのプロパティを取得および設定する Application.Properties プロパティを使用します。
アプリケーションの状態を取得して保存する アプリケーション セッション間で Application-Scope プロパティを保持および復元する」を参照してください。
リソース ファイル、コンテンツ ファイル、サイトオブオリジン ファイルなど、コード以外のデータ ファイルを管理します。 「WPF アプリケーション リソース、コンテンツ、およびデータ ファイル」を参照してください。
スタンドアロン アプリケーションでウィンドウを管理する 「WPF Windows の概要」を参照してください。
ナビゲーションの追跡と管理 ナビゲーションの概要を参照してください。

アプリケーション定義

Application クラスの機能を利用するには、アプリケーション定義を実装する必要があります。 WPF アプリケーション定義は、 Application から派生し、特別な MSBuild 設定で構成されるクラスです。

アプリケーション定義の実装

一般的な WPF アプリケーション定義は、マークアップと分離コードの両方を使用して実装されます。 これにより、マークアップを使用して、アプリケーションのプロパティ、リソースを宣言的に設定し、イベントを登録しながら、イベントを処理し、分離コードでアプリケーション固有の動作を実装することができます。

次の例は、マークアップと分離コードの両方を使用してアプリケーション定義を実装する方法を示しています。

<Application 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
  x:Class="SDKSample.App" />
using System.Windows;

namespace SDKSample
{
    public partial class App : Application { }
}

Imports System.Windows

Namespace SDKSample
    Partial Public Class App
        Inherits Application
    End Class
End Namespace

マークアップ ファイルと分離コード ファイルを連携させるには、次のことが必要です。

  • マークアップでは、 Application 要素に x:Class 属性を含める必要があります。 アプリケーションがビルドされると、マークアップ ファイルにx:Classが存在すると、MSBuild はpartialから派生し、Application属性で指定された名前を持つx:Class クラスを作成します。 これには、XAML スキーマ (xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml") の XML 名前空間宣言を追加する必要があります。

  • 分離コードでは、クラスは、マークアップのpartial属性で指定された名前と同じ名前のx:Class クラスであり、Applicationから派生する必要があります。 これにより、分離コード ファイルを、アプリケーションのビルド時にマークアップ ファイル用に生成される partial クラスに関連付けられます (「 WPF アプリケーションのビルド」を参照)。

Visual Studio を使用して新しい WPF アプリケーション プロジェクトまたは WPF ブラウザー アプリケーション プロジェクトを作成する場合、アプリケーション定義は既定で含まれており、マークアップと分離コードの両方を使用して定義されます。

このコードは、アプリケーション定義を実装するために必要な最小値です。 ただし、アプリケーションをビルドして実行する前に、アプリケーション定義に追加の MSBuild 構成を行う必要があります。

MSBuild のアプリケーション定義の構成

スタンドアロン アプリケーションと XAML ブラウザー アプリケーション (XBAP) では、実行前に特定のレベルのインフラストラクチャを実装する必要があります。 このインフラストラクチャの最も重要な部分は、エントリ ポイントです。 ユーザーがアプリケーションを起動すると、オペレーティング システムはエントリ ポイントを呼び出します。これは、アプリケーションを起動するための既知の関数です。

警告

XBAP では、Internet Explorer や古いバージョンの Firefox など、従来のブラウザーが動作する必要があります。 これらの古いブラウザーは、通常、Windows 10 および Windows 11 ではサポートされていません。 最新のブラウザーでは、セキュリティ リスクのために XBAP アプリに必要なテクノロジがサポートされなくなりました。 XBAP を有効にするプラグインはサポートされなくなりました。 詳細については、「WPF ブラウザーでホストされるアプリケーション (XBAP)についてよく寄せられる質問を参照してください。

従来、開発者はテクノロジに応じて、このコードの一部またはすべてを自分で記述する必要があります。 ただし、次の MSBuild プロジェクト ファイルに示すように、アプリケーション定義のマークアップ ファイルが MSBuild ApplicationDefinition 項目として構成されている場合、WPF によってこのコードが生成されます。

<Project
  DefaultTargets="Build"
                        xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  ...
  <ApplicationDefinition Include="App.xaml" />
  <Compile Include="App.xaml.cs" />
  ...
</Project>

ビハインド コード ファイルにはコードが含まれているため、通常どおり MSBuild Compile 項目としてマークされます。

これらの MSBuild 構成をアプリケーション定義のマークアップ ファイルと分離コード ファイルに適用すると、MSBuild は次のようなコードを生成します。

using System;
using System.Windows;

namespace SDKSample
{
    public class App : Application
    {
        public App() { }
        [STAThread]
        public static void Main()
        {
            // Create new instance of application subclass
            App app = new App();

            // Code to register events and set properties that were
            // defined in XAML in the application definition
            app.InitializeComponent();

            // Start running the application
            app.Run();
        }

        public void InitializeComponent()
        {
            // Initialization code goes here.
        }
    }
}
Imports System.Windows

Namespace SDKSample
    Public Class App
        Inherits Application
        Public Sub New()
        End Sub
        <STAThread>
        Public Shared Sub Main()
            ' Create new instance of application subclass
            Dim app As New App()

            ' Code to register events and set properties that were
            ' defined in XAML in the application definition
            app.InitializeComponent()

            ' Start running the application
            app.Run()
        End Sub

        Public Sub InitializeComponent()
            ' Initialization code goes here.	
        End Sub
    End Class
End Namespace

結果のコードは、エントリ ポイント メソッドの Mainを含む追加のインフラストラクチャ コードでアプリケーション定義を拡張します。 STAThreadAttribute属性は、WPF アプリケーションのメイン UI スレッドが WPF アプリケーションに必要な STA スレッドであることを示すために、Main メソッドに適用されます。 Main呼び出されると、App メソッドを呼び出してイベントを登録し、マークアップに実装されているプロパティを設定する前に、InitializeComponentの新しいインスタンスが作成されます。 InitializeComponentは自動的に生成されるため、InitializeComponent実装やPage実装の場合と同様に、アプリケーション定義からWindowを明示的に呼び出す必要はありません。 最後に、 Run メソッドを呼び出してアプリケーションを起動します。

現在のアプリケーションの取得

Application クラスの機能はアプリケーション間で共有されるため、ApplicationごとにAppDomain クラスのインスタンスは 1 つだけ存在できます。 これを実現するために、Application クラスはシングルトンクラスとして実装され、単一のインスタンスを生成して static プロパティで共有アクセスを提供します (Currentを参照)。

次のコードは、現在のApplicationAppDomain オブジェクトへの参照を取得する方法を示しています。

// Get current application
Application current = App.Current;
' Get current application
Dim current As Application = App.Current

Current は、 Application クラスのインスタンスへの参照を返します。 Application派生クラスへの参照が必要な場合は、次の例に示すように、Current プロパティの値をキャストする必要があります。

// Get strongly-typed current application
App app = (App)App.Current;
' Get strongly-typed current application
Dim appCurrent As App = CType(App.Current, App)

Current オブジェクトの有効期間内の任意の時点で、Applicationの値を調べることができます。 ただし、注意が必要です。 Application クラスがインスタンス化された後、Application オブジェクトの状態に一貫性がない期間があります。 この期間中、 Application は、アプリケーション インフラストラクチャの確立、プロパティの設定、イベントの登録など、コードの実行に必要なさまざまな初期化タスクを実行します。 この期間中に Application オブジェクトを使用しようとすると、特に設定されているさまざまな Application プロパティに依存している場合に、コードに予期しない結果が生じる可能性があります。

Application初期化作業が完了すると、その有効期間が本当に開始されます。

アプリケーションの有効期間

WPF アプリケーションの有効期間は、アプリケーションがいつ開始され、アクティブ化および非アクティブ化され、シャットダウンされたかを通知するために、 Application によって発生するいくつかのイベントによってマークされます。

スプラッシュ スクリーン

.NET Framework 3.5 SP1 以降では、スタートアップ ウィンドウまたは スプラッシュ画面で使用するイメージを指定できます。 SplashScreen クラスを使用すると、アプリケーションの読み込み中にスタートアップ ウィンドウを簡単に表示できます。 SplashScreen ウィンドウが作成され、Runが呼び出される前に表示されます。 詳細については、「 アプリケーションの起動時間 」および「 WPF アプリケーションへのスプラッシュスクリーンの追加」を参照してください。

アプリケーションの起動

Runが呼び出され、アプリケーションが初期化されると、アプリケーションを実行する準備が整います。 この瞬間は、 Startup イベントが発生したときに示されます。

using System.Windows;

namespace SDKSample
{
    public partial class App : Application
    {
        void App_Startup(object sender, StartupEventArgs e)
        {
            // Application is running
        }
    }
}

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private Sub App_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
            ' Application is running
            '</SnippetStartupCODEBEHIND1>
    End Class
End Namespace
'</SnippetStartupCODEBEHIND2>

アプリケーションの有効期間のこの時点で最も一般的な操作は、UI を表示することです。

ユーザー インターフェイスの表示

ほとんどのスタンドアロン Windows アプリケーションでは、実行を開始すると Window が開きます。 Startup イベント ハンドラーは、次のコードで示すように、これを行うことができる 1 つの場所です。

<Application
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.App" 
  Startup="App_Startup" />
using System.Windows;

namespace SDKSample
{
    public partial class App : Application
    {
        void App_Startup(object sender, StartupEventArgs e)
        {
            // Open a window
            MainWindow window = new MainWindow();
            window.Show();
        }
    }
}

Imports System.Windows

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private Sub App_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
            ' Open a window
            Dim window As New MainWindow()
            window.Show()
        End Sub
    End Class
End Namespace

スタンドアロン アプリケーションでインスタンス化される最初の Window は、既定でメイン アプリケーション ウィンドウになります。 この Window オブジェクトは、 Application.MainWindow プロパティによって参照されます。 最初にインスタンス化されたMainWindowとは異なるウィンドウがメイン ウィンドウである必要がある場合は、Window プロパティの値をプログラムで変更できます。

XBAP が最初に開始されると、ほとんどの場合、 Pageに移動します。 これは次のコードに示されています。

<Application 
  x:Class="SDKSample.App"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Startup="App_Startup" />
using System;
using System.Windows;
using System.Windows.Navigation;

namespace SDKSample
{
    public partial class App : Application
    {
        void App_Startup(object sender, StartupEventArgs e)
        {
            ((NavigationWindow)this.MainWindow).Navigate(new Uri("HomePage.xaml", UriKind.Relative));
        }
    }
}

Imports System.Windows
Imports System.Windows.Navigation

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private Sub App_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
            CType(Me.MainWindow, NavigationWindow).Navigate(New Uri("HomePage.xaml", UriKind.Relative))
        End Sub
    End Class
End Namespace

Startupのみを開くか、Windowに移動するようにPageを処理する場合は、代わりにマークアップでStartupUri属性を設定できます。

次の例は、スタンドアロン アプリケーションから StartupUri を使用して Windowを開く方法を示しています。

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    StartupUri="MainWindow.xaml" />

次の例は、XBAP から StartupUri を使用して Pageに移動する方法を示しています。

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    StartupUri="HomePage.xaml" />

このマークアップは、ウィンドウを開く前のコードと同じ効果を持ちます。

ナビゲーションの詳細については、「ナビゲーションの 概要」を参照してください。

パラメーターなしのコンストラクターを使用してインスタンス化する必要がある場合、またはプロパティを設定するか、イベントをサブスクライブしてから表示する必要がある場合、またはアプリケーションの起動時に指定されたコマンドライン引数を処理する必要がある場合は、 Startup イベントを処理して Window を開く必要があります。

Command-Line 引数の処理

Windows では、コマンド プロンプトまたはデスクトップからスタンドアロン アプリケーションを起動できます。 どちらの場合も、コマンド ライン引数をアプリケーションに渡すことができます。 次の例は、単一のコマンド ライン引数 "/StartMinimized" で起動されるアプリケーションを示しています。

wpfapplication.exe /StartMinimized

アプリケーションの初期化中、WPF はオペレーティング システムからコマンド ライン引数を取得し、Startup パラメーターのArgs プロパティを使用してStartupEventArgs イベント ハンドラーに渡します。 次のようなコードを使用して、コマンド ライン引数を取得して格納できます。

<Application
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.App"
  Startup="App_Startup" />
using System.Windows;

namespace SDKSample
{
    public partial class App : Application
    {
        void App_Startup(object sender, StartupEventArgs e)
        {
            // Application is running
            // Process command line args
            bool startMinimized = false;
            for (int i = 0; i != e.Args.Length; ++i)
            {
                if (e.Args[i] == "/StartMinimized")
                {
                    startMinimized = true;
                }
            }

            // Create main application window, starting minimized if specified
            MainWindow mainWindow = new MainWindow();
            if (startMinimized)
            {
                mainWindow.WindowState = WindowState.Minimized;
            }
            mainWindow.Show();
        }
    }
}

Imports System.Windows

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private Sub App_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
            ' Application is running
            ' Process command line args
            Dim startMinimized As Boolean = False
            Dim i As Integer = 0
            Do While i <> e.Args.Length
                If e.Args(i) = "/StartMinimized" Then
                    startMinimized = True
                End If
                i += 1
            Loop

            ' Create main application window, starting minimized if specified
            Dim mainWindow As New MainWindow()
            If startMinimized Then
                mainWindow.WindowState = WindowState.Minimized
            End If
            mainWindow.Show()
        End Sub
    End Class
End Namespace

このコードは、Startup コマンド ライン引数が指定されたかどうかを確認するを処理します。指定されている場合は、メイン ウィンドウが開き、WindowStateMinimizedが表示されます。 WindowState プロパティはプログラムで設定する必要があるため、メイン Windowをコードで明示的に開く必要があります。

XBAP は ClickOnce 配置を使用して起動されるため、コマンド ライン引数を取得および処理できません ( 「WPF アプリケーションの配置」を参照)。 ただし、それらを起動するために使用される URL からクエリ文字列パラメーターを取得して処理できます。

アプリケーションのアクティブ化と非アクティブ化

Windows では、ユーザーはアプリケーションを切り替えることができます。 最も一般的な方法は、Alt + Tab キーの組み合わせを使用することです。 アプリケーションは、ユーザーが選択できる表示 Window がある場合にのみ切り替えることができます。 現在選択されている Windowアクティブ ウィンドウ ( フォアグラウンド ウィンドウとも呼ばれます) であり、ユーザー入力を受け取る Window です。 アクティブ ウィンドウを持つアプリケーションは、 アクティブなアプリケーション (または フォアグラウンド アプリケーション) です。 アプリケーションは、次の状況でアクティブなアプリケーションになります。

  • 起動され、 Windowが表示されます。

  • ユーザーは、アプリケーション内の Window を選択して、別のアプリケーションから切り替えます。

Application.Activated イベントを処理することで、アプリケーションがアクティブになったときを検出できます。

同様に、アプリケーションは次の状況で非アクティブになることがあります。

  • ユーザーが現在のアプリケーションから別のアプリケーションに切り替えます。

  • アプリケーションがシャットダウンしたとき。

Application.Deactivated イベントを処理することで、アプリケーションが非アクティブになったときを検出できます。

次のコードは、 Activated イベントと Deactivated イベントを処理して、アプリケーションがアクティブかどうかを判断する方法を示しています。

<Application 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.App"
  StartupUri="MainWindow.xaml"
  Activated="App_Activated" 
  Deactivated="App_Deactivated" />
using System;
using System.Windows;

namespace SDKSample
{
    public partial class App : Application
    {
        bool isApplicationActive;

        void App_Activated(object sender, EventArgs e)
        {
            // Application activated
            this.isApplicationActive = true;
        }

        void App_Deactivated(object sender, EventArgs e)
        {
            // Application deactivated
            this.isApplicationActive = false;
        }
    }
}

Imports System.Windows

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private isApplicationActive As Boolean

        Private Sub App_Activated(ByVal sender As Object, ByVal e As EventArgs)
            ' Application activated
            Me.isApplicationActive = True
        End Sub

        Private Sub App_Deactivated(ByVal sender As Object, ByVal e As EventArgs)
            ' Application deactivated
            Me.isApplicationActive = False
        End Sub
    End Class
End Namespace

Windowは、アクティブ化および非アクティブ化することもできます。 詳細については、「Window.Activated」および「Window.Deactivated」を参照してください。

XBAP に対して Application.ActivatedApplication.Deactivated も発生しません。

アプリケーションのシャットダウン

アプリケーションがシャットダウンされると、アプリケーションの有効期間が終了します。これは、次の理由で発生する可能性があります。

  • ユーザーはすべての Windowを閉じます。

  • ユーザーがメイン Windowを閉じます。

  • ユーザーは、ログオフまたはシャットダウンして Windows セッションを終了します。

  • アプリケーション固有の条件が満たされました。

アプリケーションのシャットダウンの管理に役立つ Application は、 Shutdown メソッド、 ShutdownMode プロパティ、および SessionEnding イベントと Exit イベントを提供します。

Shutdown は、 UIPermissionを持つアプリケーションからのみ呼び出すことができます。 スタンドアロン WPF アプリケーションには常にこのアクセス許可があります。 ただし、インターネット ゾーンの部分信頼セキュリティ サンドボックスで実行されている XBAP は実行されません。

シャットダウン モード

ほとんどのアプリケーションは、すべてのウィンドウが閉じているか、メイン ウィンドウが閉じられたときにシャットダウンします。 ただし、アプリケーションがシャットダウンされるタイミングは、他のアプリケーション固有の条件によって決まる場合があります。 アプリケーションをシャットダウンする条件を指定するには、次のいずれかのShutdownMode列挙値を使用してShutdownModeを設定します。

ShutdownModeの既定値は OnLastWindowClose です。つまり、アプリケーションの最後のウィンドウがユーザーによって閉じられたときに、アプリケーションが自動的にシャットダウンされます。 ただし、メイン ウィンドウを閉じるときにアプリケーションをシャットダウンする必要がある場合は、 ShutdownModeOnMainWindowClose に設定すると、WPF によって自動的に実行されます。 これを次の例に示します。

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.App"
    ShutdownMode="OnMainWindowClose" />

アプリケーション固有のシャットダウン条件がある場合は、 ShutdownModeOnExplicitShutdown に設定します。 この場合は、 Shutdown メソッドを明示的に呼び出してアプリケーションをシャットダウンする必要があります。それ以外の場合は、すべてのウィンドウが閉じられている場合でも、アプリケーションの実行が続行されます。 ShutdownShutdownModeまたはOnLastWindowCloseである場合、OnMainWindowCloseは暗黙的に呼び出されることに注意してください。

ShutdownMode は XBAP から設定できますが、無視されます。XBAP は、ブラウザーから移動したとき、または XBAP をホストするブラウザーが閉じられたときに、常にシャットダウンされます。 詳細については、「ナビゲーションの概要」を参照してください。

セッションの終了

ShutdownMode プロパティによって記述されるシャットダウン条件は、アプリケーションに固有です。 ただし、場合によっては、外部条件の結果としてアプリケーションがシャットダウンされることがあります。 最も一般的な外部条件は、ユーザーが次のアクションによって Windows セッションを終了したときに発生します。

  • ログオフ

  • 終了しています

  • 再起動

  • 冬眠

Windows セッションがいつ終了するかを検出するには、次の例に示すように、 SessionEnding イベントを処理できます。

<Application 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.App"
    StartupUri="MainWindow.xaml"
    SessionEnding="App_SessionEnding" />
using System.Windows;

namespace SDKSample
{
    public partial class App : Application
    {
        void App_SessionEnding(object sender, SessionEndingCancelEventArgs e)
        {
            // Ask the user if they want to allow the session to end
            string msg = string.Format("{0}. End session?", e.ReasonSessionEnding);
            MessageBoxResult result = MessageBox.Show(msg, "Session Ending", MessageBoxButton.YesNo);

            // End session, if specified
            if (result == MessageBoxResult.No)
            {
                e.Cancel = true;
            }
        }
    }
}

Imports System.Windows

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private Sub App_SessionEnding(ByVal sender As Object, ByVal e As SessionEndingCancelEventArgs)
            ' Ask the user if they want to allow the session to end
            Dim msg As String = String.Format("{0}. End session?", e.ReasonSessionEnding)
            Dim result As MessageBoxResult = MessageBox.Show(msg, "Session Ending", MessageBoxButton.YesNo)

            ' End session, if specified
            If result = MessageBoxResult.No Then
                e.Cancel = True
            End If
        End Sub
    End Class
End Namespace

この例では、 ReasonSessionEnding プロパティを調べて、Windows セッションの終了方法を確認します。 この値を使用して、ユーザーに確認メッセージを表示します。 ユーザーがセッションを終了したくない場合は、Windows セッションの終了を防ぐために、 Canceltrue に設定します。

SessionEnding は XBAP では発生しません。

出口

アプリケーションがシャットダウンすると、アプリケーションの状態の保持など、最終的な処理を実行することが必要になる場合があります。 このような状況では、Exit イベント ハンドラーが次の例で行うのと同様に、App_Exit イベントを処理できます。 これは、 App.xaml ファイルのイベント ハンドラーとして定義されます。 その実装は、 App.xaml.cs ファイルと Application.xaml.vb ファイルで強調表示されています。

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.App"
    StartupUri="MainWindow.xaml" 
    Startup="App_Startup" 
    Exit="App_Exit">
    <Application.Resources>
        <SolidColorBrush x:Key="ApplicationScopeResource" Color="White"></SolidColorBrush>
    </Application.Resources>
</Application>
using System.Windows;
using System.IO;
using System.IO.IsolatedStorage;

namespace SDKSample
{
    public partial class App : Application
    {
        string filename = "App.txt";

        public App()
        {
            // Initialize application-scope property
            this.Properties["NumberOfAppSessions"] = 0;
        }

        private void App_Startup(object sender, StartupEventArgs e)
        {
            // Restore application-scope property from isolated storage
            IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForDomain();
            try
            {
                using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filename, FileMode.Open, storage))
                using (StreamReader reader = new StreamReader(stream))
                {
                    // Restore each application-scope property individually
                    while (!reader.EndOfStream)
                    {
                        string[] keyValue = reader.ReadLine().Split(new char[] {','});
                        this.Properties[keyValue[0]] = keyValue[1];
                    }
                }
            }
            catch (FileNotFoundException ex)
            {
                // Handle when file is not found in isolated storage:
                // * When the first application session
                // * When file has been deleted
            }
        }

        private void App_Exit(object sender, ExitEventArgs e)
        {
            // Persist application-scope property to isolated storage
            IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForDomain();
            using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filename, FileMode.Create, storage))
            using (StreamWriter writer = new StreamWriter(stream))
            {
                // Persist each application-scope property individually
                foreach (string key in this.Properties.Keys)
                {
                    writer.WriteLine("{0},{1}", key, this.Properties[key]);
                }
            }
        }
    }
}
Imports System.IO
Imports System.IO.IsolatedStorage

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private filename As String = "App.txt"

        Public Sub New()
            ' Initialize application-scope property
            Me.Properties("NumberOfAppSessions") = 0
        End Sub

        Private Sub App_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
            ' Restore application-scope property from isolated storage
            Dim storage As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForDomain()
            Try
                Using stream As New IsolatedStorageFileStream(filename, FileMode.Open, storage)
                Using reader As New StreamReader(stream)
                    ' Restore each application-scope property individually
                    Do While Not reader.EndOfStream
                        Dim keyValue() As String = reader.ReadLine().Split(New Char() {","c})
                        Me.Properties(keyValue(0)) = keyValue(1)
                    Loop
                End Using
                End Using
            Catch ex As FileNotFoundException
                ' Handle when file is not found in isolated storage:
                ' * When the first application session
                ' * When file has been deleted
            End Try
        End Sub

        Private Sub App_Exit(ByVal sender As Object, ByVal e As ExitEventArgs)
            ' Persist application-scope property to isolated storage
            Dim storage As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForDomain()
            Using stream As New IsolatedStorageFileStream(filename, FileMode.Create, storage)
            Using writer As New StreamWriter(stream)
                ' Persist each application-scope property individually
                For Each key As String In Me.Properties.Keys
                    writer.WriteLine("{0},{1}", key, Me.Properties(key))
                Next key
            End Using
            End Using
        End Sub
    End Class
End Namespace

完全な例については、「 アプリケーション セッション間でプロパティ Application-Scope 永続化および復元する」を参照してください。

Exit は、スタンドアロン アプリケーションと XBAP の両方で処理できます。 XBAP の場合、次の状況で Exit が発生します。

  • XBAP から離れます。

  • Internet Explorer で、XBAP をホストしているタブが閉じられるとき。

  • ブラウザーを閉じるとき。

終了コード

アプリケーションは、ほとんどの場合、ユーザーの要求に応じてオペレーティング システムによって起動されます。 ただし、特定のタスクを実行するために、別のアプリケーションによってアプリケーションを起動できます。 起動したアプリケーションがシャットダウンすると、起動アプリケーションは、起動したアプリケーションがシャットダウンした状態を知りたい場合があります。 このような状況では、Windows では、シャットダウン時にアプリケーションの終了コードを返すことができます。 既定では、WPF アプリケーションは終了コード値 0 を返します。

Visual Studio からデバッグすると、アプリケーションがシャットダウンすると、次のようなメッセージで、アプリケーションの終了コードが [出力] ウィンドウに表示されます。

The program '[5340] AWPFApp.vshost.exe: Managed' has exited with code 0 (0x0).

[表示] メニューの [出力] をクリックして [出力] ウィンドウを開きます。

終了コードを変更するには、 Shutdown(Int32) オーバーロードを呼び出します。このオーバーロードは、整数引数を終了コードとして受け入れます。

// Shutdown and return a non-default exit code
Application.Current.Shutdown(-1);
' Shutdown and return a non-default exit code
Application.Current.Shutdown(-1)

終了コードの値を検出して変更するには、 Exit イベントを処理します。 Exit イベント ハンドラーには、ExitEventArgs プロパティを使用して終了コードへのアクセスを提供するApplicationExitCodeが渡されます。 詳細については、Exitを参照してください。

スタンドアロン アプリケーションと XBAP の両方で終了コードを設定できます。 ただし、XBAP の場合、終了コード値は無視されます。

未処理の例外

予期しない例外がスローされた場合など、異常な条件下でアプリケーションがシャットダウンすることがあります。 この場合、アプリケーションに例外を検出して処理するコードがない可能性があります。 この種類の例外はハンドルされない例外です。アプリケーションが閉じられる前に、次の図に示すような通知が表示されます。

ハンドルされない例外通知を示すスクリーンショット。

ユーザー エクスペリエンスの観点からは、次の一部またはすべてを実行することで、アプリケーションでこの既定の動作を回避することをお勧めします。

  • わかりやすい情報を表示します。

  • アプリケーションの実行を維持しようとしています。

  • 開発者向けの詳細な例外情報を Windows イベント ログに記録します。

このサポートの実装は、未処理の例外を検出できることに依存します。これは、 DispatcherUnhandledException イベントが発生する対象です。

<Application
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.App"
  StartupUri="MainWindow.xaml"
  DispatcherUnhandledException="App_DispatcherUnhandledException" />
using System.Windows;
using System.Windows.Threading;

namespace SDKSample
{
    public partial class App : Application
    {
        void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            // Process unhandled exception

            // Prevent default unhandled exception processing
            e.Handled = true;
        }
    }
}
Imports System.Windows
Imports System.Windows.Threading

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private Sub App_DispatcherUnhandledException(ByVal sender As Object, ByVal e As DispatcherUnhandledExceptionEventArgs)
            ' Process unhandled exception

            ' Prevent default unhandled exception processing
            e.Handled = True
        End Sub
    End Class
End Namespace

DispatcherUnhandledException イベント ハンドラーには、例外自体 (DispatcherUnhandledExceptionEventArgs) など、ハンドルされない例外に関するコンテキスト情報を含むDispatcherUnhandledExceptionEventArgs.Exception パラメーターが渡されます。 この情報を使用して、例外の処理方法を決定できます。

DispatcherUnhandledExceptionを処理する場合は、DispatcherUnhandledExceptionEventArgs.Handled プロパティを true に設定する必要があります。それ以外の場合、WPF では例外がハンドルされないと見なされ、前に説明した既定の動作に戻ります。 ハンドルされない例外が発生し、 DispatcherUnhandledException イベントが処理されない場合、またはイベントが処理され、 Handledfalseに設定されている場合、アプリケーションはすぐにシャットダウンされます。 さらに、他の Application イベントは発生しません。 そのため、アプリケーションがシャットダウンする前に実行する必要があるコードがアプリケーションにある場合は、 DispatcherUnhandledException を処理する必要があります。

アプリケーションはハンドルされない例外の結果としてシャットダウンされる可能性がありますが、次のセクションで説明するように、通常、アプリケーションはユーザー要求に応答してシャットダウンします。

アプリケーションの有効期間イベント

スタンドアロン アプリケーションと XBAP には、まったく同じ有効期間はありません。 次の図は、スタンドアロン アプリケーションの有効期間内の主要なイベントを示し、それらが発生するシーケンスを示しています。

スタンドアロン アプリケーション - アプリケーション オブジェクト イベント

同様に、次の図は、XBAP の有効期間内の主要なイベントを示し、それらが発生するシーケンスを示しています。

XBAP - アプリケーション オブジェクト イベント

こちらも参照ください