Przegląd Zarządzanie aplikacjami

Wszystkie aplikacje mają tendencję do współużytkowania wspólnego zestawu funkcji, które mają zastosowanie do implementacji aplikacji i zarządzania nimi. Ten temat zawiera omówienie funkcji w klasie służącej Application do tworzenia aplikacji i zarządzania nimi.

klasa aplikacji

W WPF typowe funkcje o zakresie aplikacji są hermetyzowane w Application klasie. Klasa Application zawiera następujące funkcje:

  • Śledzenie i interakcja z okresem istnienia aplikacji.

  • Pobieranie i przetwarzanie parametrów wiersza polecenia.

  • Wykrywanie nieobsługiwane wyjątki i reagowanie na nieobsługiwane.

  • Udostępnianie właściwości i zasobów zakresu aplikacji.

  • Zarządzanie oknami w aplikacjach autonomicznych.

  • Śledzenie nawigacji i zarządzanie nią.

Jak wykonywać typowe zadania przy użyciu klasy aplikacji

Jeśli nie interesuje Cię wszystkie szczegóły Application klasy, w poniższej tabeli wymieniono niektóre typowe zadania i Application sposób ich wykonania. Przeglądając powiązany interfejs API i tematy, możesz znaleźć więcej informacji i przykładowy kod.

Zadanie Metoda
Pobieranie obiektu reprezentującego bieżącą aplikację Application.Current Użyj właściwości .
Dodawanie ekranu uruchamiania do aplikacji Zobacz Dodawanie ekranu powitalnego do aplikacji WPF.
Uruchamianie aplikacji Użyj metody Application.Run.
Zatrzymywanie aplikacji Shutdown Użyj metody Application.Current obiektu .
Pobieranie argumentów z wiersza polecenia Application.Startup Obsłuż zdarzenie i użyj StartupEventArgs.Args właściwości . Aby zapoznać się z przykładem, zobacz Application.Startup zdarzenie.
Pobieranie i ustawianie kodu zakończenia aplikacji ExitEventArgs.ApplicationExitCode Ustaw właściwość w procedurze Application.Exit obsługi zdarzeń lub wywołaj metodę Shutdown i przekaż liczbę całkowitą.
Wykrywanie nieobsługiwane wyjątki i reagowanie na nieobsługiwane Obsługa zdarzenia DispatcherUnhandledException .
Pobieranie i ustawianie zasobów o zakresie aplikacji Application.Resources Użyj właściwości .
Korzystanie ze słownika zasobów zakresu aplikacji Zobacz Używanie słownika zasobów zakresu aplikacji.
Pobieranie i ustawianie właściwości o zakresie aplikacji Application.Properties Użyj właściwości .
Pobieranie i zapisywanie stanu aplikacji Zobacz Utrwalanie i przywracanie właściwości zakresu aplikacji między sesjami aplikacji.
Zarządzaj plikami danych innych niż kod, w tym plikami zasobów, plikami zawartości i plikami pochodzenia lokacji. Zobacz Zasób aplikacji WPF, zawartość i pliki danych.
Zarządzanie oknami w aplikacjach autonomicznych Zobacz Omówienie systemu Windows WPF.
Śledzenie nawigacji i zarządzanie nią Zobacz Omówienie nawigacji.

Definicja aplikacji

Aby korzystać z funkcji Application klasy, należy zaimplementować definicję aplikacji. Definicja aplikacji WPF to klasa, która pochodzi z Application klasy i jest skonfigurowana przy użyciu specjalnego ustawienia MSBuild.

Implementowanie definicji aplikacji

Typowa definicja aplikacji WPF jest implementowana przy użyciu zarówno znaczników, jak i kodu za pomocą kodu. Dzięki temu można używać znaczników do deklaratywnego ustawiania właściwości aplikacji, zasobów i rejestrowania zdarzeń podczas obsługi zdarzeń i implementowania zachowania specyficznego dla aplikacji w kodzie.

W poniższym przykładzie pokazano, jak zaimplementować definicję aplikacji przy użyciu znaczników i kodu za pomocą kodu:

<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

Aby umożliwić współdziałanie pliku znaczników i pliku kodu, należy wykonać następujące czynności:

  • W znacznikach element Application musi zawierać atrybut x:Class. Gdy aplikacja jest kompilowana, istnienie x:Class elementu w pliku znaczników powoduje, że program MSBuild tworzy klasę pochodzącą partial z Application klasy i ma nazwę określoną przez x:Class atrybut . Wymaga to dodania deklaracji przestrzeni nazw XML dla schematu XAML (xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml").

  • W kodzie klasa musi być klasą partial o takiej samej nazwie, która jest określona przez x:Class atrybut w adiustacji i musi pochodzić z Applicationklasy . Dzięki temu plik za kodem może być skojarzony z klasą partial , która jest generowana dla pliku znaczników podczas kompilowania aplikacji (zobacz Tworzenie aplikacji WPF).

Uwaga

Podczas tworzenia nowego projektu aplikacji WPF lub projektu aplikacji przeglądarki WPF przy użyciu programu Visual Studio definicja aplikacji jest domyślnie uwzględniana i jest definiowana przy użyciu zarówno znaczników, jak i kodu.

Ten kod jest minimalnym wymaganym do zaimplementowania definicji aplikacji. Należy jednak wykonać dodatkową konfigurację programu MSBuild do definicji aplikacji przed utworzeniem i uruchomieniem aplikacji.

Konfigurowanie definicji aplikacji dla programu MSBuild

Aplikacje autonomiczne i aplikacje przeglądarki XAML (XBAPs) wymagają implementacji określonego poziomu infrastruktury, zanim będą mogły działać. Najważniejszą częścią tej infrastruktury jest punkt wejścia. Gdy aplikacja jest uruchamiana przez użytkownika, system operacyjny wywołuje punkt wejścia, który jest dobrze znaną funkcją uruchamiania aplikacji.

Ostrzeżenie

XBAPs wymagają obsługi starszych przeglądarek, takich jak Internet Explorer i Firefox. Te starsze wersje przeglądarki są zwykle nieobsługiwane w systemach Windows 10 i Windows 11. Nowoczesne przeglądarki nie obsługują już technologii wymaganej dla aplikacji XBAP ze względu na zagrożenia bezpieczeństwa. Wtyczki obsługujące XBAPs nie są już obsługiwane.

Tradycyjnie deweloperzy musieli napisać jakiś lub cały ten kod samodzielnie, w zależności od technologii. Jednak WPF generuje ten kod, gdy plik znaczników definicji aplikacji jest skonfigurowany jako element MSBuild, jak pokazano w następującym pliku projektu MSBuild ApplicationDefinition :

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

Ponieważ plik z kodem zawiera kod, jest on oznaczony jako element MSBuild Compile , tak jak zwykle.

Zastosowanie tych konfiguracji programu MSBuild do plików znaczników i kodu w definicji aplikacji powoduje, że program MSBuild generuje kod podobny do następującego:

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

Wynikowy kod rozszerza definicję aplikacji o dodatkowy kod infrastruktury, który zawiera metodę Mainpunktu wejścia . Atrybut STAThreadAttribute jest stosowany do Main metody, aby wskazać, że główny wątek interfejsu użytkownika dla aplikacji WPF jest wątkiem STA, który jest wymagany dla aplikacji WPF. Po wywołaniu Main tworzy nowe wystąpienie App klasy przed wywołaniem InitializeComponent metody w celu zarejestrowania zdarzeń i ustawienia właściwości implementowanych w adiustacji. Ponieważ InitializeComponent jest generowany dla Ciebie, nie musisz jawnie wywoływać InitializeComponent z definicji aplikacji, takiej jak w przypadku Page implementacji i Window . Na koniec wywoływana Run jest metoda , aby uruchomić aplikację.

Pobieranie bieżącej aplikacji

Ponieważ funkcje Application klasy są współużytkowane przez aplikację, może istnieć tylko jedno wystąpienie Application klasy na klasę .AppDomain Aby to wymusić, Application klasa jest implementowana jako pojedyncza klasa (zobacz Implementowanie pojedynczegotonu w języku C#), która tworzy pojedyncze wystąpienie samego siebie i zapewnia współużytkowany dostęp do niej za pomocą staticCurrent właściwości .

Poniższy kod pokazuje, jak uzyskać odwołanie do Application obiektu dla bieżącego AppDomainobiektu .

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

Current Zwraca odwołanie do wystąpienia Application klasy. Jeśli chcesz odwołać się do Application klasy pochodnej, musisz rzutować wartość Current właściwości, jak pokazano w poniższym przykładzie.

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

Możesz sprawdzić wartość Current w dowolnym momencie okresu istnienia Application obiektu. Należy jednak zachować ostrożność. Po utworzeniu Application wystąpienia klasy występuje okres, w którym stan Application obiektu jest niespójny. W tym okresie Application wykonuje różne zadania inicjowania, które są wymagane przez kod do uruchomienia, w tym ustanawianie infrastruktury aplikacji, ustawianie właściwości i rejestrowanie zdarzeń. Jeśli spróbujesz użyć Application obiektu w tym okresie, kod może mieć nieoczekiwane wyniki, szczególnie jeśli zależy to od różnych Application ustawionych właściwości.

Kiedy Application kończy swoją pracę inicjaliza, jego okres istnienia naprawdę się zaczyna.

Okres istnienia aplikacji

Okres istnienia aplikacji WPF jest oznaczony przez kilka zdarzeń zgłaszanych przez Application usługę , aby poinformować o tym, kiedy aplikacja została uruchomiona, została aktywowana i zdezaktywowana i została zamknięta.

Ekran powitalny

Począwszy od programu .NET Framework 3.5 SP1, można określić obraz do użycia w oknie uruchamiania lub ekran powitalny. Klasa SplashScreen ułatwia wyświetlanie okna uruchamiania podczas ładowania aplikacji. Okno SplashScreen jest tworzone i wyświetlane przed Run wywołaniami. Aby uzyskać więcej informacji, zobacz Czas uruchamiania aplikacji i Dodawanie ekranu powitalnego do aplikacji WPF.

Uruchamianie aplikacji

Po Run wywołaniu i zainicjowaniu aplikacji aplikacja jest gotowa do uruchomienia. Ten moment jest oznaczany, gdy Startup zdarzenie zostanie zgłoszone:

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>

W tym momencie w okresie istnienia aplikacji najczęstszą rzeczą do zrobienia jest pokazanie interfejsu użytkownika.

Wyświetlanie interfejsu użytkownika

Większość autonomicznych aplikacji systemu Windows otwiera się Window po rozpoczęciu działania. Procedura Startup obsługi zdarzeń to jedna lokalizacja, z której można to zrobić, jak pokazano w poniższym kodzie.

<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

Uwaga

Pierwsze Window wystąpienie w aplikacji autonomicznej staje się domyślnie głównym oknem aplikacji. Ten Window obiekt jest przywołyyny przez Application.MainWindow właściwość . Wartość MainWindow właściwości można zmienić programowo, jeśli okno inne niż pierwsze wystąpienie Window powinno być głównym oknem.

Po pierwszym uruchomieniu XBAP najprawdopodobniej przejdzie do elementu Page. Jest to pokazane w poniższym kodzie.

<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

Jeśli obsługujesz Startup tylko otwieranie elementu Window lub przechodzenie do Pageelementu , możesz ustawić StartupUri atrybut w znaczniku.

W poniższym przykładzie pokazano, jak używać StartupUri elementu z autonomicznej aplikacji do otwierania obiektu Window.

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

W poniższym przykładzie pokazano, jak używać z StartupUri XBAP, aby przejść do elementu Page.

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

Ten znacznik ma taki sam efekt jak poprzedni kod podczas otwierania okna.

Uwaga

Aby uzyskać więcej informacji na temat nawigacji, zobacz Omówienie nawigacji.

Musisz obsłużyć Startup zdarzenie, aby otworzyć Window zdarzenie, jeśli musisz utworzyć wystąpienie go przy użyciu konstruktora bez parametrów lub musisz ustawić jego właściwości lub zasubskrybować jego zdarzenia przed jego wyświetleniem lub musisz przetworzyć wszystkie argumenty wiersza polecenia, które zostały podane podczas uruchamiania aplikacji.

Przetwarzanie argumentów wiersza polecenia

W systemie Windows aplikacje autonomiczne można uruchamiać z poziomu wiersza polecenia lub pulpitu. W obu przypadkach argumenty wiersza polecenia można przekazać do aplikacji. W poniższym przykładzie pokazano aplikację uruchamianą z pojedynczym argumentem wiersza polecenia "/StartMinimized":

wpfapplication.exe /StartMinimized

Podczas inicjowania aplikacji WPF pobiera argumenty wiersza polecenia z systemu operacyjnego i przekazuje je do Startup procedury obsługi zdarzeń za pośrednictwem Args właściwości parametru StartupEventArgs . Argumenty wiersza polecenia można pobierać i przechowywać przy użyciu kodu podobnego do poniższego.

<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

Kod obsługuje Startup sprawdzanie, czy został podany argument wiersza polecenia /StartMinimized . Jeśli tak, otwiera główne okno z wartością WindowStateMinimized. Należy pamiętać, że ponieważ WindowState właściwość musi być ustawiona programowo, należy jawnie otworzyć obiekt main Window w kodzie.

XBAPs nie może pobrać i przetworzyć argumentów wiersza polecenia, ponieważ są one uruchamiane przy użyciu wdrożenia ClickOnce (zobacz Wdrażanie aplikacji WPF). Mogą jednak pobierać i przetwarzać parametry ciągu zapytania z adresów URL używanych do ich uruchamiania.

Aktywacja i dezaktywacja aplikacji

System Windows umożliwia użytkownikom przełączanie się między aplikacjami. Najczęstszym sposobem jest użycie kombinacji klawiszy ALT+TAB. Aplikację można przełączyć na tylko wtedy, gdy jest widoczna Window , którą użytkownik może wybrać. Aktualnie wybrane Window jest aktywne okno (znane również jako okno pierwszego planu) i jest toWindow, które odbiera dane wejściowe użytkownika. Aplikacja z aktywnym oknem jest aktywną aplikacją (lub aplikacją pierwszego planu). Aplikacja staje się aktywną aplikacją w następujących okolicznościach:

  • Jest on uruchamiany i pokazuje wartość Window.

  • Użytkownik przełącza się z innej aplikacji, wybierając element Window w aplikacji.

Możesz wykryć, kiedy aplikacja stanie się aktywna, obsługując Application.Activated zdarzenie.

Podobnie aplikacja może stać się nieaktywna w następujących okolicznościach:

  • Użytkownik przełącza się do innej aplikacji z bieżącej.

  • Gdy aplikacja zostanie zamknięta.

Możesz wykryć, kiedy aplikacja stanie się nieaktywna, obsługując Application.Deactivated zdarzenie.

Poniższy kod pokazuje, jak obsługiwać Activated zdarzenia i Deactivated w celu określenia, czy aplikacja jest aktywna.

<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

Element Window można również aktywować i dezaktywować. Zobacz Window.Activated i Window.Deactivated , aby uzyskać więcej informacji.

Uwaga

Ani nie Application.ActivatedApplication.Deactivated jest zgłaszany dla XBAPs.

Zamykanie aplikacji

Okres działania aplikacji kończy się po zamknięciu, co może wystąpić z następujących powodów:

  • Użytkownik zamyka każdy Windowelement .

  • Użytkownik zamyka główny Windowelement .

  • Użytkownik kończy sesję systemu Windows, logując się lub zamykając.

  • Warunek specyficzny dla aplikacji został spełniony.

Aby ułatwić zarządzanie zamykaniem aplikacji, Application udostępnia Shutdown metodę, ShutdownMode właściwość oraz SessionEnding zdarzenia i Exit .

Uwaga

Shutdown można wywoływać tylko z aplikacji, które mają wartość UIPermission. Autonomiczne aplikacje WPF zawsze mają to uprawnienie. Jednak XBAPs uruchomione w strefie internetowej w piaskownicy zabezpieczeń częściowych zaufania nie.

Tryb zamykania

Większość aplikacji jest zamykana po zamknięciu wszystkich okien lub zamknięciu okna głównego. Czasami jednak inne warunki specyficzne dla aplikacji mogą określić, kiedy aplikacja zostanie zamknięta. Możesz określić warunki, w których aplikacja zostanie zamknięta, ustawiając ShutdownMode jedną z następujących ShutdownMode wartości wyliczenia:

Wartość ShutdownMode domyślna to OnLastWindowClose, co oznacza, że aplikacja automatycznie zamyka się po zamknięciu ostatniego okna w aplikacji przez użytkownika. Jeśli jednak aplikacja powinna zostać zamknięta po zamknięciu okna głównego, WPF automatycznie to robi, jeśli ustawiono wartość ShutdownModeOnMainWindowClose. Jest to pokazane w następującym przykładzie.

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

W przypadku warunków zamknięcia specyficznych dla aplikacji należy ustawić wartość ShutdownModeOnExplicitShutdown. W takim przypadku twoim zadaniem jest zamknięcie aplikacji przez jawne wywołanie Shutdown metody. W przeciwnym razie aplikacja będzie nadal działać, nawet jeśli wszystkie okna są zamknięte. Należy pamiętać, że Shutdown element jest wywoływany niejawnie, gdy element ShutdownMode ma OnLastWindowClose wartość lub OnMainWindowClose.

Uwaga

ShutdownMode można ustawić z XBAP, ale jest ignorowany; XBAP jest zawsze zamykany po przejściu z dala od przeglądarki lub po zamknięciu przeglądarki, która hostuje XBAP. Aby uzyskać więcej informacji, zobacz Omówienie nawigacji.

Zakończenie sesji

Warunki zamknięcia opisane przez ShutdownMode właściwość są specyficzne dla aplikacji. Jednak w niektórych przypadkach aplikacja może zostać zamknięta w wyniku stanu zewnętrznego. Najczęstszym warunkiem zewnętrznym jest zakończenie sesji systemu Windows przez następujące akcje:

  • Wylogowanie

  • Zamykanie

  • Ponowne uruchomienie

  • Hibernacji

Aby wykryć, kiedy kończy się sesja systemu Windows, możesz obsłużyć SessionEnding zdarzenie, jak pokazano w poniższym przykładzie.

<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

W tym przykładzie kod sprawdza właściwość, ReasonSessionEnding aby określić, jak kończy się sesja systemu Windows. Ta wartość służy do wyświetlania użytkownikowi komunikatu potwierdzenia. Jeśli użytkownik nie chce, aby sesja zakończyła się, kod ustawia wartość Cancel , aby true zapobiec zakończeniu sesji systemu Windows.

Uwaga

SessionEnding nie jest zgłaszany dla XBAPs.

Zakończ

Po zamknięciu aplikacji może być konieczne przeprowadzenie końcowego przetwarzania, takiego jak utrwalanie stanu aplikacji. W takich sytuacjach można obsłużyć Exit zdarzenie, ponieważ App_Exit program obsługi zdarzeń wykonuje w poniższym przykładzie. Jest on definiowany jako program obsługi zdarzeń w pliku App.xaml . Jego implementacja jest wyróżniona w plikach App.xaml.cs i 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

Aby uzyskać pełny przykład, zobacz Utrwalanie i przywracanie właściwości zakresu aplikacji między sesjami aplikacji.

Exit można obsługiwać zarówno przez aplikacje autonomiczne, jak i XBAPs. W przypadku protokołu XBAPs Exit jest wywoływany w następujących okolicznościach:

  • XBAP jest odchodzi od.

  • W programie Internet Explorer, gdy karta hostująca XBAP jest zamknięta.

  • Po zamknięciu przeglądarki.

Kod zakończenia

Aplikacje są uruchamiane głównie przez system operacyjny w odpowiedzi na żądanie użytkownika. Można jednak uruchomić aplikację przez inną aplikację, aby wykonać określone zadanie. Po zamknięciu uruchomionej aplikacji uruchomienie aplikacji może chcieć znać warunek, w którym uruchomiona aplikacja została zamknięta. W takich sytuacjach system Windows umożliwia aplikacjom zwrócenie kodu zakończenia aplikacji po zamknięciu. Domyślnie aplikacje WPF zwracają wartość kodu zakończenia 0.

Uwaga

Podczas debugowania z programu Visual Studio kod zakończenia aplikacji jest wyświetlany w oknie Dane wyjściowe po zamknięciu aplikacji w komunikacie, który wygląda następująco:

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

Zostanie otwarte okno Dane wyjściowe, klikając pozycję Dane wyjściowe w menu Widok.

Aby zmienić kod zakończenia, możesz wywołać Shutdown(Int32) przeciążenie, które akceptuje argument liczby całkowitej jako kod zakończenia:

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

Możesz wykryć wartość kodu zakończenia i zmienić go, obsługując Exit zdarzenie. Procedura Exit obsługi zdarzeń jest przekazywana, ExitEventArgs która zapewnia dostęp do kodu zakończenia z właściwością ApplicationExitCode . Aby uzyskać więcej informacji, zobacz Exit.

Uwaga

Kod zakończenia można ustawić zarówno w aplikacjach autonomicznych, jak i XBAPs. Jednak wartość kodu zakończenia jest ignorowana dla XBAPs.

Nieobsługiwane wyjątki

Czasami aplikacja może zostać zamknięta w nietypowych warunkach, takich jak zgłoszenie nieprzewidzianego wyjątku. W takim przypadku aplikacja może nie mieć kodu do wykrywania i przetwarzania wyjątku. Ten typ wyjątku jest nieobsługiwanym wyjątkiem; przed zamknięciem aplikacji zostanie wyświetlone powiadomienie podobne do przedstawionego na poniższym rysunku.

Screenshot that shows an unhandled exception notification.

Z perspektywy środowiska użytkownika lepiej jest, aby aplikacja unikała tego domyślnego zachowania, wykonując niektóre lub wszystkie następujące czynności:

  • Wyświetlanie przyjaznych dla użytkownika informacji.

  • Próba zachowania działania aplikacji.

  • Rejestrowanie szczegółowych informacji o wyjątkach przyjaznych dla deweloperów w dzienniku zdarzeń systemu Windows.

Zaimplementowanie tej obsługi zależy od możliwości wykrywania nieobsługiwanych wyjątków, co oznacza, że DispatcherUnhandledException zdarzenie jest zgłaszane.

<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

Procedura DispatcherUnhandledException obsługi zdarzeń jest przekazywana DispatcherUnhandledExceptionEventArgs parametr zawierający informacje kontekstowe dotyczące nieobsługiwanego wyjątku, w tym samego wyjątku (DispatcherUnhandledExceptionEventArgs.Exception). Te informacje umożliwiają określenie sposobu obsługi wyjątku.

W przypadku obsługi DispatcherUnhandledExceptionmetody należy ustawić DispatcherUnhandledExceptionEventArgs.Handled właściwość na true; w przeciwnym razie WPF nadal uznaje wyjątek za nieobsługiwany i przywraca domyślne zachowanie opisane wcześniej. Jeśli zgłaszany jest nieobsługiwany wyjątek i DispatcherUnhandledException zdarzenie nie jest obsługiwane lub zdarzenie jest obsługiwane i Handled jest ustawione na falsewartość , aplikacja zostanie natychmiast zamknięta. Ponadto nie są wywoływane żadne inne Application zdarzenia. W związku z tym należy obsługiwać DispatcherUnhandledException , jeśli aplikacja ma kod, który musi zostać uruchomiony przed zamknięciem aplikacji.

Mimo że aplikacja może zostać zamknięta w wyniku nieobsługiwanego wyjątku, aplikacja zwykle zamyka się w odpowiedzi na żądanie użytkownika, zgodnie z opisem w następnej sekcji.

Zdarzenia okresu istnienia aplikacji

Aplikacje autonomiczne i XBAPs nie mają dokładnie tych samych okresów istnienia. Na poniższej ilustracji przedstawiono kluczowe zdarzenia w okresie istnienia aplikacji autonomicznej i przedstawiono sekwencję, w której są zgłaszane.

Standalone Application - Application Object Events

Podobnie na poniższej ilustracji przedstawiono kluczowe zdarzenia w okresie istnienia XBAP i przedstawiono sekwencję, w której są one wywoływane.

XBAP - Application Object Events

Zobacz też