Freigeben über


Anwendungsverwaltung – Übersicht

Alle Anwendungen verwenden in der Regel einen gemeinsamen Satz von Funktionen, die für die Anwendungsimplementierung und -verwaltung gelten. Dieses Thema enthält eine Übersicht über die Funktionalität in der Application Klasse zum Erstellen und Verwalten von Anwendungen.

Die Anwendungsklasse

In WPF wird die allgemeine Anwendungsbereichsfunktion in der Application Klasse gekapselt. Die Application Klasse enthält die folgenden Funktionen:

  • Nachverfolgen und Interagieren mit der Anwendungslebensdauer.

  • Abrufen und Verarbeiten von Befehlszeilenparametern.

  • Erkennen und Reagieren auf unbehandelte Ausnahmen.

  • Freigeben von Anwendungsbereichseigenschaften und -ressourcen.

  • Verwalten von Fenstern in eigenständigen Anwendungen.

  • Nachverfolgen und Verwalten der Navigation.

So führen Sie allgemeine Aufgaben mithilfe der Anwendungsklasse aus

Wenn Sie nicht an allen Details der Application-Klasse interessiert sind, zeigt die folgende Tabelle einige der allgemeinen Aufgaben für Application und wie Sie diese ausführen können. Wenn Sie die zugehörigen APIs und Themen anzeigen, finden Sie weitere Informationen und Beispielcode.

Aufgabe Vorgehensweise
Abrufen eines Objekts, das die aktuelle Anwendung darstellt Verwenden Sie die Application.Current-Eigenschaft.
Hinzufügen eines Startbildschirms zu einer Anwendung Siehe Hinzufügen eines Begrüßungsbildschirms zu einer WPF-Anwendung.
Starten einer Anwendung Verwenden Sie die Application.Run-Methode.
Beenden einer Anwendung Verwenden Sie die Shutdown Methode des Application.Current Objekts.
Abrufen von Argumenten aus der Befehlszeile Behandeln Sie das Application.Startup Ereignis und verwenden Sie die StartupEventArgs.Args Eigenschaft. Ein Beispiel finden Sie unter dem Application.Startup Ereignis.
Abrufen und Festlegen des Anwendungsausgangscodes Legen Sie die ExitEventArgs.ApplicationExitCode Eigenschaft im Application.Exit Ereignishandler fest, oder rufen Sie die Shutdown Methode auf, und übergeben Sie eine ganze Zahl.
Erkennen und Reagieren auf unbehandelte Ausnahmen Behandeln Sie das DispatcherUnhandledException Ereignis.
Abrufen und Einstellen von anwendungsspezifischen Ressourcen Verwenden Sie die Application.Resources-Eigenschaft.
Verwenden eines Ressourcenwörterbuchs für den Anwendungsbereich Siehe Verwenden eines Application-Scope Ressourcenwörterbuchs.
Abrufen und Festlegen von Eigenschaften mit Anwendungsbereich Verwenden Sie die Application.Properties-Eigenschaft.
Abrufen und Speichern des Zustands einer Anwendung Siehe Persist and Restore Application-Scope Properties across Application Sessions.
Verwalten von Nicht-Code-Datendateien, einschließlich Ressourcendateien, Inhaltsdateien und Ursprungsdateien der Website. Siehe WPF-Anwendungsressource, -Inhalte und -Datendateien.
Verwalten von Fenstern in eigenständigen Anwendungen Siehe WPF Windows Overview.
Nachverfolgen und Verwalten der Navigation Siehe Navigationsübersicht.

Die Anwendungsdefinition

Um die Funktionalität der Application Klasse zu nutzen, müssen Sie eine Anwendungsdefinition implementieren. Eine WPF-Anwendungsdefinition ist eine Klasse, die von Application einer speziellen MSBuild-Einstellung abgeleitet und konfiguriert wird.

Implementieren einer Anwendungsdefinition

Eine typische WPF-Anwendungsdefinition wird mit Markup und Code-Behind implementiert. Auf diese Weise können Sie Markup verwenden, um Anwendungseigenschaften, Ressourcen und Registerereignisse deklarativ festzulegen, während Ereignisse behandelt und anwendungsspezifisches Verhalten in CodeBehind implementiert werden.

Das folgende Beispiel zeigt, wie Sie eine Anwendungsdefinition mit Markup und CodeBehind implementieren:

<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

Damit eine Markupdatei und eine CodeBehind-Datei zusammenarbeiten können, müssen die folgenden Schritte ausgeführt werden:

  • Im Markup muss das Application-Element das attribut x:Class enthalten. Wenn die Anwendung erstellt wird, führt das Vorhandensein von x:Class in der Markupdatei dazu, dass MSBuild eine partial-Klasse erstellt, die von der Application-Klasse abgeleitet ist und den Namen aufweist, der durch das x:Class-Attribut angegeben wird. Dies erfordert das Hinzufügen einer XML-Namespacedeklaration für das XAML-Schema (xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml").

  • Im CodeBehind muss es sich bei der Klasse um eine partial Klasse mit demselben Namen handeln, der durch das x:Class Attribut im Markup angegeben wird und von Application abgeleitet werden muss. Auf diese Weise kann die CodeBehind-Datei mit der partial-Klasse verknüpft werden, die beim Erstellen der Anwendung (siehe Erstellen einer WPF-Anwendung) für die Markupdatei generiert wird.

Hinweis

Wenn Sie ein neues WPF-Anwendungsprojekt oder ein WPF-Browseranwendungsprojekt mit Visual Studio erstellen, ist standardmäßig eine Anwendungsdefinition enthalten und wird sowohl mit Markup als auch mit CodeBehind definiert.

Dieser Code ist das Minimum, das zum Implementieren einer Anwendungsdefinition erforderlich ist. Vor dem Erstellen und Ausführen der Anwendung muss jedoch eine zusätzliche MSBuild-Konfiguration an die Anwendungsdefinition vorgenommen werden.

Konfigurieren der Anwendungsdefinition für MSBuild

Eigenständige Anwendungen und XAML-Browseranwendungen (XBAPs) erfordern die Implementierung einer bestimmten Infrastrukturebene, bevor sie ausgeführt werden können. Der wichtigste Teil dieser Infrastruktur ist der Einstiegspunkt. Wenn eine Anwendung von einem Benutzer gestartet wird, ruft das Betriebssystem den Einstiegspunkt auf, der eine bekannte Funktion zum Starten von Anwendungen ist.

Warnung

XBAPs erfordern, dass ältere Browser funktionieren, z. B. Internet Explorer und alte Versionen von Firefox. Diese älteren Browser werden in der Regel unter Windows 10 und Windows 11 nicht unterstützt. Moderne Browser unterstützen die für XBAP-Apps erforderliche Technologie aufgrund von Sicherheitsrisiken nicht mehr. Plug-Ins, die XBAPs aktivieren, werden nicht mehr unterstützt. Weitere Informationen finden Sie unter Häufig gestellte Fragen zu WPF-Anwendungen, die im Browser gehostet werden (XBAP).

Traditionell müssen Entwickler je nach Technologie einige oder alle diesen Code für sich selbst schreiben. WPF generiert diesen Code jedoch für Sie, wenn die Markupdatei Ihrer Anwendungsdefinition als MSBuild-Element ApplicationDefinition konfiguriert ist, wie in der folgenden MSBuild-Projektdatei gezeigt:

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

Da die CodeBehind-Datei Code enthält, wird sie wie gewohnt als MSBuild-Element Compile markiert.

Die Anwendung dieser MSBuild-Konfigurationen auf die Markup- und CodeBehind-Dateien einer Anwendungsdefinition bewirkt, dass MSBuild Code wie folgt generiert:

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

Der resultierende Code erweitert Ihre Anwendungsdefinition mit zusätzlichem Infrastrukturcode, der die Einstiegspunktmethode Mainenthält. Das STAThreadAttribute Attribut wird auf die Main Methode angewendet, um anzugeben, dass der Haupt-UI-Thread für die WPF-Anwendung ein STA-Thread ist, der für WPF-Anwendungen erforderlich ist. Wenn Main aufgerufen wird, erstellt es eine neue Instanz von App und ruft dann die InitializeComponent Methode auf, um die Ereignisse zu registrieren und die Eigenschaften festzulegen, die im Markup implementiert sind. Da InitializeComponent für Sie generiert wird, müssen Sie nicht explizit aus einer Anwendungsdefinition aufrufen InitializeComponent , wie sie für Page und Window Implementierungen verwendet wird. Schließlich wird die Run Methode aufgerufen, um die Anwendung zu starten.

Abrufen der aktuellen Anwendung

Da die Funktionalität der Application Klasse in einer Anwendung gemeinsam genutzt wird, kann es nur eine Instanz der Application Klasse pro AppDomain geben. Um dies zu erzwingen, wird die Application Klasse als Singleton-Klasse implementiert (siehe Implementieren von Singleton in C#), die eine einzelne Instanz von sich selbst erstellt und über die staticCurrent Eigenschaft gemeinsamen Zugriff bietet.

Der folgende Code zeigt, wie ein Verweis auf das Application-Objekt für die aktuelle AppDomain erworben wird.

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

Current gibt einen Verweis auf eine Instanz der Application Klasse zurück. Wenn Sie eine Referenz auf die Application abgeleitete Klasse benötigen, müssen Sie den Wert in der Eigenschaft Current umwandeln, wie dies im folgenden Beispiel gezeigt wird.

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

Sie können den Wert eines Current Objekts zu einem beliebigen Zeitpunkt in der Lebensdauer eines Application Objekts prüfen. Sie sollten jedoch vorsichtig sein. Nachdem die Application Klasse instanziiert wurde, gibt es einen Punkt, in dem der Zustand des Application Objekts inkonsistent ist. Während dieses Zeitraums führt Application die verschiedenen Initialisierungsaufgaben aus, die von Ihrem Code ausgeführt werden müssen, einschließlich des Einrichtens der Anwendungsinfrastruktur, Festlegen von Eigenschaften und Registrieren von Ereignissen. Wenn Sie versuchen, das Application Objekt während dieses Zeitraums zu verwenden, hat Ihr Code möglicherweise unerwartete Ergebnisse, insbesondere, wenn es von den verschiedenen Application Eigenschaften abhängt, die festgelegt werden.

Wenn Application seine Initialisierungsarbeit abgeschlossen hat, beginnt der Lebenszyklus wirklich.

Anwendungslebensdauer

Die Lebensdauer einer WPF-Anwendung wird durch mehrere Ereignisse gekennzeichnet, die Application ausgelöst werden, um Sie darüber zu informieren, wann Ihre Anwendung gestartet wurde, aktiviert und deaktiviert wurde und heruntergefahren wurde.

Begrüßungsbildschirm

Ab .NET Framework 3.5 SP1 können Sie ein Bild angeben, das in einem Startfenster oder begrüßungsbildschirm verwendet werden soll. Die SplashScreen Klasse erleichtert das Anzeigen eines Startfensters während des Ladens der Anwendung. Das SplashScreen Fenster wird erstellt und vor dem Run Aufruf angezeigt. Weitere Informationen finden Sie unter Anwendungsstartzeit und Hinzufügen eines Begrüßungsbildschirms zu einer WPF-Anwendung.

Starten einer Anwendung

Nachdem Run aufgerufen und die Anwendung initialisiert wurde, ist sie bereit zur Ausführung. Dieser Moment ist gekennzeichnet, wenn das Startup Ereignis ausgelöst wird:

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>

An diesem Punkt in der Lebensdauer einer Anwendung besteht die am häufigsten zu tunde Vorgehensweise darin, eine Benutzeroberfläche anzuzeigen.

Anzeigen einer Benutzeroberfläche

Die meisten eigenständigen Windows-Anwendungen öffnen eine Window, sobald sie gestartet werden. Der Startup Ereignishandler ist eine Stelle, von der aus Sie dies tun können, wie im folgenden Code veranschaulicht.

<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

Hinweis

Der erste Window , der in einer eigenständigen Anwendung instanziiert werden soll, wird standardmäßig zum Hauptanwendungsfenster. Auf dieses Window Objekt wird von der Application.MainWindow Eigenschaft verwiesen. Der Wert der MainWindow Eigenschaft kann programmgesteuert geändert werden, wenn ein anderes Fenster als das erste Instanziierte Window das Hauptfenster sein soll.

Wenn ein XBAP zum ersten Mal gestartet wird, navigiert es höchstwahrscheinlich zu einem Page. Dies wird im folgenden Code gezeigt.

<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

Wenn Sie nur Startup ein Window Attribut öffnen oder zu einem Pagenavigieren, können Sie stattdessen das StartupUri Attribut im Markup festlegen.

Das folgende Beispiel zeigt, wie Sie die StartupUri aus einer eigenständigen Anwendung heraus zum Öffnen einer Window verwenden können.

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

Das folgende Beispiel zeigt, wie Sie StartupUri von einem XBAP verwenden, um zu einem Page zu navigieren.

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

Dieses Markup hat die gleiche Auswirkung wie der vorherige Code zum Öffnen eines Fensters.

Hinweis

Weitere Informationen zur Navigation finden Sie in der Navigationsübersicht.

Sie müssen das Startup Ereignis behandeln, um ein Window Ereignis zu öffnen, wenn Sie es mithilfe eines nicht parameterlosen Konstruktors instanziieren müssen, oder sie müssen seine Eigenschaften festlegen oder seine Ereignisse abonnieren, bevor es angezeigt wird, oder Sie müssen alle Befehlszeilenargumente verarbeiten, die beim Starten der Anwendung angegeben wurden.

Verarbeiten von Command-Line Argumenten

In Windows können eigenständige Anwendungen entweder über eine Eingabeaufforderung oder über den Desktop gestartet werden. In beiden Fällen können Befehlszeilenargumente an die Anwendung übergeben werden. Das folgende Beispiel zeigt eine Anwendung, die mit einem einzigen Befehlszeilenargument "/StartMinimized" gestartet wird:

wpfapplication.exe /StartMinimized

Während der Anwendungsinitialisierung ruft WPF die Befehlszeilenargumente vom Betriebssystem ab und übergibt sie über die Startup Eigenschaft des Args Parameters an den StartupEventArgs Ereignishandler. Sie können die Befehlszeilenargumente mithilfe von Code wie den folgenden abrufen und speichern.

<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

Der Code behandelt Startup , um zu überprüfen, ob das Befehlszeilenargument "/StartMinimized " angegeben wurde. Wenn ja, wird das Hauptfenster mit einem WindowState von Minimizedgeöffnet. Beachten Sie, dass die WindowState-Eigenschaft programmgesteuert festgelegt werden muss. Daher muss das Hauptobjekt Window explizit im Code geöffnet werden.

XBAPs können Befehlszeilenargumente nicht abrufen und verarbeiten, da sie mithilfe der ClickOnce-Bereitstellung gestartet werden (siehe Bereitstellen einer WPF-Anwendung). Sie können jedoch Abfragezeichenfolgenparameter aus den URLs abrufen und verarbeiten, die zum Starten verwendet werden.

Anwendungsaktivierung und Deaktivierung

Windows ermöglicht Es Benutzern, zwischen Anwendungen zu wechseln. Die am häufigsten verwendete Methode besteht darin, die TASTENKOMBINATION ALT+TAB zu verwenden. Eine Anwendung kann nur umgeschaltet werden, wenn sie ein sichtbares Window hat, das ein Benutzer auswählen kann. Das derzeit ausgewählte Window Fenster ist das aktive Fenster (auch als Vordergrundfenster bezeichnet) und ist das Window Fenster, das Benutzereingaben empfängt. Die Anwendung mit dem aktiven Fenster ist die aktive Anwendung (oder Vordergrundanwendung). Eine Anwendung wird unter folgenden Umständen zur aktiven Anwendung:

  • Es wird gestartet und zeigt ein Window.

  • Ein Benutzer wechselt von einer anderen Anwendung, indem er eine Window in der Anwendung auswählt.

Sie können erkennen, wann eine Anwendung aktiv wird, indem Sie das Application.Activated Ereignis behandeln.

Ebenso kann eine Anwendung unter folgenden Umständen inaktiv werden:

  • Ein Benutzer wechselt von der aktuellen Anwendung zu einer anderen Anwendung.

  • Wenn die Anwendung heruntergefahren wird.

Sie können erkennen, wann eine Anwendung inaktiv wird, indem Sie das Application.Deactivated Ereignis behandeln.

Der folgende Code zeigt, wie die Ereignisse Activated und Deactivated behandelt werden, um zu bestimmen, ob eine Anwendung aktiv ist.

<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

Ein Window kann auch aktiviert und deaktiviert werden. Weitere Informationen finden Sie unter Window.Activated und Window.Deactivated.

Hinweis

Weder Application.Activated noch Application.Deactivated wird für XBAPs ausgelöst.

Herunterfahren der Anwendung

Die Lebensdauer einer Anwendung endet, wenn sie heruntergefahren wird, was aus folgenden Gründen auftreten kann:

  • Ein Benutzer schließt jedes Window.

  • Ein Benutzer schließt das Hauptsteuerelement Window.

  • Ein Benutzer beendet die Windows-Sitzung, indem er sich abmeldet oder den Computer herunterfährt.

  • Es wurde eine anwendungsspezifische Bedingung erfüllt.

Um das Herunterfahren der Anwendung zu unterstützen, stellen Application die Shutdown-Methode, die ShutdownMode-Eigenschaft und die SessionEnding- sowie Exit-Ereignisse bereit.

Hinweis

Shutdown kann nur von Anwendungen aufgerufen werden, die über UIPermission. Eigenständige WPF-Anwendungen verfügen immer über diese Berechtigung. XBAPs, die in der Internetzone mit einer teilweise vertrauenswürdigen Sicherheits-Sandbox ausgeführt werden, tun dies jedoch nicht.

Herunterfahren-Modus

Die meisten Anwendungen werden entweder heruntergefahren, wenn alle Fenster geschlossen werden oder wenn das Hauptfenster geschlossen wird. Manchmal können jedoch andere anwendungsspezifische Bedingungen bestimmen, wann eine Anwendung heruntergefahren wird. Sie können die Bedingungen angeben, unter denen Ihre Anwendung heruntergefahren wird, indem Sie ShutdownMode mit einem der folgenden ShutdownMode Enumerationswerte festlegen.

Der Standardwert ShutdownMode ist OnLastWindowClose, was bedeutet, dass eine Anwendung automatisch heruntergefahren wird, wenn das letzte Fenster in der Anwendung vom Benutzer geschlossen wird. Jedoch wird die Anwendung automatisch geschlossen, wenn das Hauptfenster geschlossen wird, falls Sie ShutdownMode auf OnMainWindowClose setzen. Dies wird im folgenden Beispiel gezeigt.

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

Wenn Sie anwendungsspezifische Bedingungen für das Herunterfahren festlegen, setzen Sie ShutdownMode auf OnExplicitShutdown. In diesem Fall liegt es in Ihrer Verantwortung, eine Anwendung durch explizites Aufrufen der Shutdown Methode herunterzufahren. Andernfalls wird die Anwendung weiterhin ausgeführt, auch wenn alle Fenster geschlossen sind. Beachten Sie, dass Shutdown implizit aufgerufen wird, wenn ShutdownMode entweder OnLastWindowClose oder OnMainWindowClose ist.

Hinweis

ShutdownMode kann von einem XBAP festgelegt werden, wird jedoch ignoriert; Ein XBAP wird immer heruntergefahren, wenn er von einem Browser weg navigiert wird oder wenn der Browser, der die XBAP hostet, geschlossen wird. Weitere Informationen finden Sie unter Übersicht über die Navigation.

Sitzungsende

Die Abschaltbedingungen, die durch die ShutdownMode Eigenschaft beschrieben werden, sind spezifisch für eine Anwendung. In einigen Fällen kann eine Anwendung jedoch aufgrund einer externen Bedingung beendet werden. Die häufigste externe Bedingung tritt auf, wenn ein Benutzer die Windows-Sitzung durch die folgenden Aktionen beendet:

  • Abmelden

  • Herunterfahren

  • Neustarten

  • Überwinternd

Um zu erkennen, wann eine Windows-Sitzung endet, können Sie das SessionEnding Ereignis behandeln, wie im folgenden Beispiel dargestellt.

<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

In diesem Beispiel prüft der Code die ReasonSessionEnding Eigenschaft, um zu bestimmen, wie die Windows-Sitzung beendet wird. Dieser Wert wird verwendet, um dem Benutzer eine Bestätigungsmeldung anzuzeigen. Wenn der Benutzer nicht möchte, dass die Sitzung endet, wird der Code so festgelegt, dass Cancel zu true gesetzt wird, um zu verhindern, dass die Windows-Sitzung endet.

Hinweis

SessionEnding wird für XBAPs nicht ausgelöst.

Ausgang

Wenn eine Anwendung heruntergefahren wird, muss sie möglicherweise eine endgültige Verarbeitung durchführen, z. B. den beibehaltenen Anwendungsstatus. In diesen Situationen können Sie das Exit Ereignis behandeln, so wie es der App_Exit Ereignishandler im folgenden Beispiel tut. Sie wird als Ereignishandler in der Datei "App.xaml " definiert. Die Implementierung wird in den Dateien App.xaml.cs und Application.xaml.vb hervorgehoben.

<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

Das vollständige Beispiel finden Sie unter "Persist and Restore Application-Scope Properties Across Application Sessions".

Exit kann sowohl von eigenständigen Anwendungen als auch von XBAPs behandelt werden. Bei XBAPs tritt Exit unter den folgenden Umständen auf:

  • Ein XBAP wird weg navigiert.

  • Wenn in Internet Explorer die Registerkarte, auf der die XBAP gehostet wird, geschlossen wird.

  • Wenn der Browser geschlossen wird.

Exitcode

Anwendungen werden hauptsächlich vom Betriebssystem als Reaktion auf eine Benutzeranforderung gestartet. Eine Anwendung kann jedoch von einer anderen Anwendung gestartet werden, um eine bestimmte Aufgabe auszuführen. Wenn die gestartete Anwendung heruntergefahren wird, möchte die Startanwendung möglicherweise die Bedingung kennen, unter der die gestartete Anwendung heruntergefahren wird. In diesen Situationen ermöglicht Windows Anwendungen das Zurückgeben eines Anwendungsausgangscodes beim Herunterfahren. WPF-Anwendungen geben standardmäßig den Ausgangscodewert 0 zurück.

Hinweis

Wenn Sie aus Visual Studio debuggen, wird der Anwendungsausgangscode im Ausgabefenster angezeigt, wenn die Anwendung heruntergefahren wird, in einer Meldung, die wie folgt aussieht:

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

Sie öffnen das Ausgabefenster, indem Sie im Menü "Ansicht" auf "Ausgabe" klicken.

Um den Ausgangscode zu ändern, können Sie die Shutdown(Int32) Überladung aufrufen, die ein ganzzahliges Argument als Ausgangscode akzeptiert:

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

Sie können den Wert des Ausgangscodes erkennen und ändern, indem Sie das Exit Ereignis behandeln. Der Exit Ereignishandler erhält ein ExitEventArgs, das Zugriff auf den Exitcode über die ApplicationExitCode-Eigenschaft ermöglicht. Weitere Informationen finden Sie unter Exit.

Hinweis

Sie können den Ausgangscode sowohl in eigenständigen Anwendungen als auch in XBAPs festlegen. Der Ausgangscodewert wird jedoch für XBAPs ignoriert.

Nicht behandelte Ausnahmen

Manchmal wird eine Anwendung unter ungewöhnlichen Bedingungen heruntergefahren, z. B. wenn eine unerwartete Ausnahme ausgelöst wird. In diesem Fall verfügt die Anwendung möglicherweise nicht über den Code zum Erkennen und Verarbeiten der Ausnahme. Diese Ausnahmeart ist eine unbehandelte Ausnahme; Eine Benachrichtigung ähnlich wie in der folgenden Abbildung dargestellt wird angezeigt, bevor die Anwendung geschlossen wird.

Screenshot, das eine Mitteilung über eine unbehandelte Ausnahme zeigt.

Aus Sicht der Benutzererfahrung ist es für eine Anwendung besser, dieses Standardverhalten zu vermeiden, indem sie einige oder alle der folgenden Aktionen ausführen:

  • Anzeigen von benutzerfreundlichen Informationen.

  • Es wird versucht, eine Anwendung am Laufen zu halten.

  • Aufzeichnen detaillierter, entwicklerfreundlicher Ausnahmeinformationen im Windows-Ereignisprotokoll.

Die Implementierung dieser Unterstützung hängt davon ab, dass unbehandelte Ausnahmen erkannt werden können, für die das DispatcherUnhandledException Ereignis ausgelöst wird.

<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

Der DispatcherUnhandledException Ereignishandler wird einen DispatcherUnhandledExceptionEventArgs Parameter übergeben, der kontextbezogene Informationen zur unbehandelten Ausnahme enthält, einschließlich der Ausnahme selbst (DispatcherUnhandledExceptionEventArgs.Exception). Mithilfe dieser Informationen können Sie bestimmen, wie die Ausnahme behandelt wird.

Bei der Bearbeitung von DispatcherUnhandledException sollten Sie die DispatcherUnhandledExceptionEventArgs.Handled-Eigenschaft auf true setzen; andernfalls betrachtet WPF weiterhin die Ausnahme als unbehandelt und kehrt auf das zuvor beschriebene Standardverhalten zurück. Wenn eine unbehandelte Ausnahme ausgelöst wird und entweder das DispatcherUnhandledException Ereignis nicht behandelt wird oder das Ereignis behandelt wird und Handled auf false festgelegt ist, wird die Anwendung sofort heruntergefahren. Darüber hinaus werden keine anderen Application Ereignisse ausgelöst. Daher müssen Sie mit DispatcherUnhandledException umgehen, wenn Ihre Anwendung Code enthält, der ausgeführt werden muss, bevor die Anwendung heruntergefahren wird.

Obwohl eine Anwendung aufgrund einer unbehandelten Ausnahme heruntergefahren werden kann, wird eine Anwendung in der Regel als Reaktion auf eine Benutzeranforderung heruntergefahren, wie im nächsten Abschnitt beschrieben.

Anwendungslebensdauer-Ereignisse

Eigenständige Anwendungen und XBAPs haben nicht genau dieselbe Lebensdauer. Die folgende Abbildung zeigt die wichtigsten Ereignisse in der Lebensdauer einer eigenständigen Anwendung und zeigt die Reihenfolge, in der sie ausgelöst werden.

Eigenständige Anwendung – Anwendungsobjektereignisse

Ebenso veranschaulicht die folgende Abbildung die wichtigsten Ereignisse während der Lebensdauer eines XBAP und zeigt die Reihenfolge, in der sie ausgelöst werden.

XBAP – Anwendungsobjektereignisse

Siehe auch