Partager via


Vue d’ensemble de la gestion des applications

Toutes les applications ont tendance à partager un ensemble commun de fonctionnalités qui s’appliquent à l’implémentation et à la gestion des applications. Cette rubrique fournit une vue d’ensemble des fonctionnalités de la classe Application pour la création et la gestion d’applications.

Classe Application

Dans WPF, les fonctions courantes dans l’étendue de l’application sont encapsulées dans la classe Application. La Application classe inclut les fonctionnalités suivantes :

  • Suivi et interaction avec la durée de vie de l’application.

  • Récupération et traitement des paramètres de ligne de commande.

  • Détection et réponse aux exceptions non gérées.

  • Partage des propriétés et des ressources à l'échelle de l'application.

  • Gestion des fenêtres dans les applications autonomes.

  • Suivi et gestion de la navigation.

Comment effectuer des tâches courantes à l’aide de la classe d’application

Si vous n’êtes pas intéressé par tous les détails de la classe Application, le tableau suivant répertorie certaines des tâches courantes pour Application et comment les accomplir. En consultant l’API et les rubriques associées, vous trouverez plus d’informations et d’exemples de code.

Tâche Approche
Obtenir un objet qui représente l’application actuelle Utilisez la propriété Application.Current.
Ajouter un écran de démarrage à une application Voir Ajouter un écran de démarrage à une application WPF.
Démarrer une application Utiliser la méthode Application.Run.
Arrêter une application Utilisez la Shutdown méthode de l’objet Application.Current .
Obtenir des arguments à partir de la ligne de commande Gérez l’événement Application.Startup et utilisez la StartupEventArgs.Args propriété. Pour obtenir un exemple, consultez l’événement Application.Startup .
Obtenir et définir le code de sortie de l’application Définissez la ExitEventArgs.ApplicationExitCode propriété dans le Application.Exit gestionnaire d’événements ou appelez la Shutdown méthode et transmettez un entier.
Détecter et répondre aux exceptions non gérées Gérez l’événement DispatcherUnhandledException.
Obtenir et définir des ressources délimitées à l’application Utilisez la propriété Application.Resources.
Utiliser un dictionnaire de ressources d’étendue d’application Consultez Utiliser un dictionnaire de ressources Application-Scope.
Obtenir et définir des propriétés au niveau de l'application Utilisez la propriété Application.Properties.
Obtenir et enregistrer l’état d’une application Voir Persister et Restaurer les Propriétés Application-Scope Entre les Sessions d’Application.
Gérez les fichiers de données non codés, y compris les fichiers de ressources, les fichiers de contenu et les fichiers de site d’origine. Consultez la ressource d’application WPF, le contenu et les fichiers de données.
Gérer les fenêtres dans les applications autonomes Consultez la vue d’ensemble de WPF Windows.
Suivre et gérer la navigation Consultez La vue d’ensemble de la navigation.

Définition de l’application

Pour utiliser les fonctionnalités de la Application classe, vous devez implémenter une définition d’application. Une définition d’application WPF est une classe qui dérive de Application et est configurée avec un paramètre MSBuild spécial.

Implémentation d’une définition d’application

Une définition d’application WPF classique est implémentée à l’aide du balisage et du code-behind. Cela vous permet d’utiliser le balisage pour définir de manière déclarative les propriétés, ressources et inscrire des événements, tout en gérant les événements et en implémentant un comportement spécifique à l’application dans le code-behind.

L’exemple suivant montre comment implémenter une définition d’application à l’aide du balisage et du code-behind :

<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

Pour permettre à un fichier de balisage et un fichier code-behind de fonctionner ensemble, les éléments suivants doivent se produire :

  • Dans le balisage, l’élément Application doit inclure l’attribut x:Class . Lorsque l’application est générée, l’existence de x:Class dans le fichier de balisage entraîne la création d’une classe partial qui dérive de Application et dont le nom est spécifié par l’attribut x:Class. Cela nécessite l’ajout d’une déclaration d’espace de noms XML pour le schéma XAML (xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml").

  • Dans code-behind, la classe doit être une partial classe portant le même nom que celui spécifié par l’attribut dans le x:Class balisage et doit dériver de Application. Cela permet au fichier code-behind d’être associé à la partial classe générée pour le fichier de balisage lorsque l’application est générée (voir Génération d’une application WPF).

Remarque

Lorsque vous créez un projet d’application WPF ou un projet d’application de navigateur WPF à l’aide de Visual Studio, une définition d’application est incluse par défaut et est définie à l’aide du balisage et du code-behind.

Ce code est le minimum requis pour implémenter une définition d’application. Toutefois, une configuration MSBuild supplémentaire doit être effectuée dans la définition de l’application avant de générer et d’exécuter l’application.

Configuration de la définition d’application pour MSBuild

Les applications autonomes et les applications de navigateur XAML (XBAPs) nécessitent l’implémentation d’un certain niveau d’infrastructure avant de pouvoir s’exécuter. La partie la plus importante de cette infrastructure est le point d’entrée. Lorsqu’une application est lancée par un utilisateur, le système d’exploitation appelle le point d’entrée, qui est une fonction connue pour démarrer des applications.

Avertissement

Les XBAPs nécessitent des navigateurs anciens pour fonctionner, tels qu’Internet Explorer et les anciennes versions de Firefox. Ces navigateurs plus anciens ne sont généralement pas pris en charge sur Windows 10 et Windows 11. Les navigateurs modernes ne prennent plus en charge la technologie requise pour les applications XBAP en raison des risques de sécurité. Les plug-ins qui activent les XBAPs ne sont plus pris en charge. Pour plus d’informations, consultez Questions fréquemment posées sur les applications WPF hébergées dans un navigateur (XBAP).

Traditionnellement, les développeurs ont besoin d’écrire tout ou partie de ce code pour eux-mêmes, en fonction de la technologie. Toutefois, WPF génère ce code pour vous lorsque le fichier de balisage de votre définition d’application est configuré en tant qu’élément MSBuild ApplicationDefinition , comme indiqué dans le fichier projet MSBuild suivant :

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

Étant donné que le fichier code-behind contient du code, il est marqué comme élément MSBuild Compile , comme c’est normal.

L’application de ces configurations MSBuild aux fichiers de balisage et de code-behind d’une définition d’application entraîne MSBuild à générer du code semblable à ce qui suit :

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

Le code résultant augmente votre définition d’application avec du code d’infrastructure supplémentaire, qui inclut la méthode Mainde point d’entrée. L’attribut STAThreadAttribute est appliqué à la Main méthode pour indiquer que le thread d’interface utilisateur principal de l’application WPF est un thread STA, requis pour les applications WPF. Lorsqu'elle est appelée, Main crée une nouvelle instance de App avant d'appeler la méthode InitializeComponent pour inscrire les événements et définir les propriétés implémentées dans le balisage. Étant donné que InitializeComponent est généré pour vous, vous n’avez pas besoin d’appeler explicitement InitializeComponent à partir d’une définition d’application comme vous le faites pour les implémentations de Page et Window. Enfin, la Run méthode est appelée pour démarrer l’application.

Récupération de l'application actuelle

Étant donné que les fonctionnalités de la Application classe sont partagées entre une application, il ne peut y avoir qu’une seule instance de la Application classe par AppDomain. Pour appliquer cela, la Application classe est implémentée en tant que classe singleton (voir Implémentation de Singleton en C#), qui crée une instance unique de lui-même et fournit un accès partagé à celle-ci avec la staticCurrent propriété.

Le code suivant montre comment acquérir une référence à l'objet Application pour le AppDomain actuel.

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

Current retourne une référence à une instance de la Application classe. Si vous souhaitez obtenir une référence à votre Application classe dérivée, vous devez caster la valeur de la Current propriété, comme illustré dans l’exemple suivant.

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

Vous pouvez inspecter la valeur d’un Current point quelconque dans la durée de vie d’un Application objet. Toutefois, vous devez être prudent. Une fois la Application classe instanciée, il existe une période pendant laquelle l’état de l’objet Application est incohérent. Pendant cette période, Application effectue les différentes tâches d’initialisation requises par votre code pour s’exécuter, notamment l’établissement de l’infrastructure d’application, la définition des propriétés et l’inscription d’événements. Si vous essayez d’utiliser l’objet Application pendant cette période, votre code peut avoir des résultats inattendus, en particulier s’il dépend des différentes Application propriétés définies.

Une fois Application son travail d’initialisation terminé, sa durée de vie commence vraiment.

Durée de vie de l’application

La durée de vie d’une application WPF est marquée par plusieurs événements déclenchés par Application pour vous informer lorsque votre application a démarré, a été activée, désactivée, puis arrêtée.

Écran de démarrage

À compter du .NET Framework 3.5 SP1, vous pouvez spécifier une image à utiliser dans une fenêtre de démarrage ou un écran de démarrage. La SplashScreen classe facilite l’affichage d’une fenêtre de démarrage pendant le chargement de votre application. La SplashScreen fenêtre est créée et affichée avant Run d’être appelée. Pour plus d’informations, consultez l’heure de démarrage de l’application et l’ajout d’un écran de démarrage à une application WPF.

Démarrage d’une application

Une fois Run appelée et l’application initialisée, l’application est prête à s’exécuter. Ce moment est marqué lorsque l'événement Startup est déclenché :

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>

À ce stade de la durée de vie d’une application, la chose la plus courante consiste à afficher une interface utilisateur.

Affichage d’une interface utilisateur

La plupart des applications Windows autonomes ouvrent un Window moment où elles commencent à s’exécuter. Le Startup gestionnaire d’événements est un emplacement à partir duquel vous pouvez effectuer cette opération, comme illustré par le code suivant.

<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

Remarque

La première Window à instancier dans une application autonome devient la fenêtre principale de l’application par défaut. Cet Window objet est référencé par la Application.MainWindow propriété. La valeur de la MainWindow propriété peut être modifiée par programmation si une fenêtre différente de la première instanciée Window doit être la fenêtre principale.

Quand un XBAP démarre pour la première fois, il accède probablement à un Page. Ceci est illustré dans le code suivant.

<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

Si vous gérez Startup uniquement pour ouvrir un Window ou accéder à un Page, vous pouvez plutôt définir l’attribut StartupUri dans le balisage.

L'exemple suivant montre comment utiliser StartupUri depuis une application autonome pour ouvrir un Window.

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

L’exemple suivant montre comment utiliser StartupUri à partir d’un XBAP pour accéder à un Page.

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

Ce balisage a le même effet que le code précédent pour ouvrir une fenêtre.

Remarque

Pour plus d’informations sur la navigation, consultez Vue d’ensemble de la navigation.

Vous devez gérer l’événement Startup pour ouvrir un Window événement si vous devez l’instancier à l’aide d’un constructeur sans paramètre, ou vous devez définir ses propriétés ou vous abonner à ses événements avant de l’afficher, ou vous devez traiter les arguments de ligne de commande fournis lors du lancement de l’application.

Traitement des arguments Command-Line

Dans Windows, les applications autonomes peuvent être lancées à partir d’une invite de commande ou du bureau. Dans les deux cas, les arguments de ligne de commande peuvent être passés à l’application. L’exemple suivant montre une application lancée avec un seul argument de ligne de commande , « /StartMinimized » :

wpfapplication.exe /StartMinimized

Lors de l’initialisation de l’application, WPF récupère les arguments de ligne de commande du système d’exploitation et les transmet au Startup gestionnaire d’événements via la Args propriété du StartupEventArgs paramètre. Vous pouvez récupérer et stocker les arguments de ligne de commande à l’aide de code comme suit.

<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

Le code gère Startup pour vérifier si l’argument de ligne de commande /StartMinimized a été fourni ; dans ce cas, il ouvre la fenêtre principale avec un WindowState de Minimized. Notez que, étant donné que la WindowState propriété doit être définie par programmation, la principale Window doit être ouverte explicitement dans le code.

Les XBAPs ne peuvent pas récupérer et traiter les arguments de ligne de commande, car ils sont lancés à l’aide du déploiement ClickOnce (voir Déploiement d’une application WPF). Toutefois, ils peuvent récupérer et traiter des paramètres de chaîne de requête à partir des URL utilisées pour les lancer.

Activation et désactivation des applications

Windows permet aux utilisateurs de basculer entre les applications. La méthode la plus courante consiste à utiliser la combinaison de touches ALT+TAB. Une application ne peut être passée en revue que si elle dispose d'un Window visible qu'un utilisateur peut sélectionner. La fenêtre actuellement sélectionnée Window est la fenêtre active (également appelée fenêtre de premier plan) et reçoit l’entrée Window de l’utilisateur. L’application avec la fenêtre active est l’application active (ou l’application de premier plan). Une application devient l’application active dans les circonstances suivantes :

  • Il est lancé et montre un Window.

  • Un utilisateur passe d’une application à une autre en sélectionnant un Window.

Vous pouvez détecter quand une application devient active en gérant l’événement Application.Activated .

De même, une application peut devenir inactive dans les circonstances suivantes :

  • Un utilisateur bascule vers une autre application à partir de l’application actuelle.

  • Lorsque l’application s’arrête.

Vous pouvez détecter quand une application devient inactive en gérant l’événement Application.Deactivated .

Le code suivant montre comment gérer les événements Activated et Deactivated pour déterminer si une application est active.

<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

Un Window peut également être activé et désactivé. Pour plus d'informations, consultez Window.Activated et Window.Deactivated.

Remarque

Ni n’est Application.ActivatedApplication.Deactivated élevé pour les adresses XBAPs.

Arrêt de l’application

La durée de vie d’une application se termine lorsqu’elle est arrêtée, ce qui peut se produire pour les raisons suivantes :

  • Un utilisateur ferme tous les Window.

  • Un utilisateur ferme le module principal Window.

  • Un utilisateur met fin à la session Windows en désactivant ou en arrêtant.

  • Une condition spécifique à l’application a été remplie.

Pour vous aider à gérer l’arrêt de l’application, Application fournit la méthode, la ShutdownShutdownMode propriété et les SessionEndingExit événements.

Remarque

Shutdown ne peut être appelé qu’à partir d’applications qui ont UIPermission. Les applications WPF autonomes ont toujours cette autorisation. Toutefois, les XBAPs s’exécutant dans le bac à sable de sécurité de confiance partielle de la zone Internet ne fonctionnent pas.

Mode d’arrêt

La plupart des applications s’arrêtent lorsque toutes les fenêtres sont fermées ou lorsque la fenêtre principale est fermée. Toutefois, parfois, d’autres conditions spécifiques à l’application peuvent déterminer quand une application s’arrête. Vous pouvez spécifier les conditions dans lesquelles votre application s’arrête en définissant ShutdownMode l’une des valeurs d’énumération suivantes ShutdownMode :

La valeur ShutdownMode par défaut est OnLastWindowClose, ce qui signifie qu’une application s’arrête automatiquement lorsque la dernière fenêtre de l’application est fermée par l’utilisateur. Toutefois, si votre application doit être arrêtée lorsque la fenêtre principale est fermée, WPF le fait automatiquement si vous définissez ShutdownModeOnMainWindowClosesur . Ceci est illustré dans l’exemple suivant.

<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" />

Lorsque vous avez des conditions d’arrêt spécifiques à l’application, vous définissez ShutdownMode sur OnExplicitShutdown. Dans ce cas, il est de votre responsabilité d’arrêter une application en appelant explicitement la Shutdown méthode ; sinon, votre application continue à s’exécuter même si toutes les fenêtres sont fermées. Notez que Shutdown est appelée implicitement lorsque ShutdownMode est soit OnLastWindowClose soit OnMainWindowClose.

Remarque

ShutdownMode peut être défini à partir d’un XBAP, mais il est ignoré ; un XBAP est toujours arrêté lorsqu’il est éloigné d’un navigateur ou lorsque le navigateur qui héberge le XBAP est fermé. Pour plus d’informations, consultez Vue d’ensemble de la navigation.

Fin de session

Les conditions d’arrêt décrites par la ShutdownMode propriété sont spécifiques à une application. Dans certains cas, toutefois, une application peut s’arrêter à la suite d’une condition externe. La condition externe la plus courante se produit lorsqu’un utilisateur met fin à la session Windows en procédant comme suit :

  • Déconnexion

  • Fermeture

  • Redémarrage

  • En hibernation

Pour détecter la fin d’une session Windows, vous pouvez gérer l’événement SessionEnding , comme illustré dans l’exemple suivant.

<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

Dans cet exemple, le code inspecte la ReasonSessionEnding propriété pour déterminer la fin de la session Windows. Elle utilise cette valeur pour afficher un message de confirmation à l’utilisateur. Si l'utilisateur ne souhaite pas que la session se termine, le code définit Cancel à true pour empêcher la session Windows de se terminer.

Remarque

SessionEnding n’est pas déclenché pour les XBAP.

Quitter

Lorsqu’une application s’arrête, il peut être nécessaire d’effectuer un traitement final, tel que la persistance de l’état de l’application. Pour ces situations, vous pouvez gérer l’événement Exit , comme le fait le App_Exit gestionnaire d’événements dans l’exemple suivant. Il est défini en tant que gestionnaire d’événements dans le fichier App.xaml . Son implémentation est mise en surbrillance dans les fichiers App.xaml.cs et 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

Pour obtenir l’exemple complet, consultez Conserver et restaurer Application-Scope propriétés entre les sessions d’application.

Exit peut être géré par les applications autonomes et les XBAPs. Pour les XBAPs, Exit est déclenché dans les circonstances suivantes :

  • La navigation quitte un XBAP.

  • Dans Internet Explorer, lorsque l’onglet qui héberge le XBAP est fermé.

  • Lorsque le navigateur est fermé.

Code de sortie

Les applications sont principalement lancées par le système d’exploitation en réponse à une demande utilisateur. Toutefois, une application peut être lancée par une autre application pour effectuer une tâche spécifique. Lorsque l’application lancée s’arrête, l’application de lancement peut souhaiter connaître la condition dans laquelle l’application lancée s’arrête. Dans ces situations, Windows permet aux applications de retourner un code de sortie d’application lors de l’arrêt. Par défaut, les applications WPF retournent une valeur de code de sortie de 0.

Remarque

Lorsque vous déboguez à partir de Visual Studio, le code de sortie de l’application s’affiche dans la fenêtre Sortie lorsque l’application s’arrête, dans un message qui ressemble à ce qui suit :

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

Vous ouvrez la fenêtre Sortie en cliquant sur Sortie dans le menu Affichage .

Pour modifier le code de sortie, vous pouvez appeler la Shutdown(Int32) surcharge, qui accepte un argument entier comme code de sortie :

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

Vous pouvez détecter la valeur du code de sortie et le modifier en gérant l’événement Exit . Le Exit gestionnaire d’événements est passé, ExitEventArgs qui fournit l’accès au code de sortie avec la ApplicationExitCode propriété. Pour plus d’informations, consultez Exit.

Remarque

Vous pouvez définir le code de sortie dans les applications autonomes et les XBAPs. Toutefois, la valeur du code de sortie est ignorée pour les XBAP.

Exceptions non gérées

Parfois, une application peut s’arrêter dans des conditions anormales, par exemple lorsqu’une exception inattendue est levée. Dans ce cas, l’application peut ne pas avoir le code pour détecter et traiter l’exception. Ce type d’exception est une exception non gérée ; une notification similaire à celle illustrée dans la figure suivante s’affiche avant la fermeture de l’application.

Capture d’écran montrant une notification d’exception non gérée.

Du point de vue de l’expérience utilisateur, il est préférable pour une application d’éviter ce comportement par défaut en effectuant certaines ou toutes les opérations suivantes :

  • Affichage d’informations conviviales.

  • Tentative de maintenir une application en cours d'exécution.

  • Enregistrement d’informations détaillées sur les exceptions conviviales pour les développeurs dans le journal des événements Windows.

L’implémentation de cette prise en charge dépend de la possibilité de détecter des exceptions non gérées, ce qui correspond à ce que l’événement DispatcherUnhandledException est déclenché.

<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

Le gestionnaire d'événements DispatcherUnhandledException reçoit un paramètre DispatcherUnhandledExceptionEventArgs qui contient des informations contextuelles concernant l'exception non gérée, y compris l'exception elle-même (DispatcherUnhandledExceptionEventArgs.Exception). Vous pouvez utiliser ces informations pour déterminer comment gérer l’exception.

Lorsque vous gérez DispatcherUnhandledException, vous devez définir la propriété DispatcherUnhandledExceptionEventArgs.Handled sur true; sinon, WPF considère encore l’exception comme non gérée et revient au comportement par défaut décrit précédemment. Si une exception non gérée est levée et que l’événement DispatcherUnhandledException n’est pas géré, ou si l’événement est géré et que Handled est défini sur false, l’application s’arrête immédiatement. Aucun autre événement Application n'est déclenché, en outre. Par conséquent, vous devez gérer DispatcherUnhandledException si votre application a du code qui doit s’exécuter avant l’arrêt de l’application.

Bien qu’une application puisse s’arrêter suite à une exception non gérée, une application s’arrête généralement en réponse à une demande utilisateur, comme indiqué dans la section suivante.

Événements de durée de vie des applications

Les applications autonomes et les XBAPs n’ont pas exactement les mêmes durées de vie. La figure suivante illustre les événements clés dans la durée de vie d’une application autonome et montre la séquence dans laquelle elles sont déclenchées.

Application autonome - Événements d’objet d’application

De même, la figure suivante illustre les événements clés dans la durée de vie d’un XBAP et montre la séquence dans laquelle ils sont déclenchés.

XBAP - Événements d’objet d’application

Voir aussi