Compartilhar via


Visão geral do gerenciamento de aplicativos

Todos os aplicativos tendem a compartilhar um conjunto comum de funcionalidades que se aplica à implementação e ao gerenciamento de aplicativos. Este tópico fornece uma visão geral da funcionalidade na Application classe para criar e gerenciar aplicativos.

A classe de aplicativo

No WPF, a funcionalidade comum no escopo do aplicativo é encapsulada na Application classe. A Application classe inclui a seguinte funcionalidade:

  • Acompanhamento e interação com o ciclo de vida do aplicativo.

  • Recuperando e processando parâmetros de linha de comando.

  • Detectando e respondendo a exceções não tratadas.

  • Compartilhamento de propriedades e recursos do escopo do aplicativo.

  • Gerenciando janelas em aplicativos autônomos.

  • Acompanhamento e gerenciamento de navegação.

Como executar tarefas comuns usando a classe de aplicativo

Se você não estiver interessado em todos os detalhes da Application classe, a tabela a seguir lista algumas das tarefas comuns de Application e como realizá-las. Ao exibir a API e os tópicos relacionados, você pode encontrar mais informações e código de exemplo.

Tarefa Abordagem
Obter um objeto que representa o aplicativo atual Use a propriedade Application.Current.
Adicionar uma tela de inicialização a um aplicativo Consulte Adicionar uma tela inicial a um aplicativo WPF.
Iniciar um aplicativo Use o método Application.Run.
Parar um aplicativo Use o Shutdown método do Application.Current objeto.
Obter argumentos da linha de comando Manipule o Application.Startup evento e use a StartupEventArgs.Args propriedade. Para obter um exemplo, consulte o Application.Startup evento.
Obter e definir o código de saída do aplicativo Defina a ExitEventArgs.ApplicationExitCode propriedade no Application.Exit manipulador de eventos ou chame o Shutdown método e passe um inteiro.
Detectar e responder a exceções não tratadas Manipule o evento DispatcherUnhandledException.
Obter e definir recursos no escopo do aplicativo Use a propriedade Application.Resources.
Utilize um dicionário de recursos no escopo do aplicativo Consulte "Usar um dicionário de recursos Application-Scope".
Obter e definir propriedades no escopo do aplicativo Use a propriedade Application.Properties.
Obter e salvar o estado de um aplicativo Consulte Persistir e Restaurar Propriedades Application-Scope Entre Sessões de Aplicação.
Gerencie arquivos de dados sem código, incluindo arquivos de recurso, arquivos de conteúdo e arquivos de site de origem. Consulte o recurso, o conteúdo e os arquivos de dados do aplicativo WPF.
Gerenciar janelas em aplicativos autônomos Confira a visão geral do WPF Windows.
Acompanhar e gerenciar a navegação Confira a visão geral da navegação.

A definição do aplicativo

Para utilizar a funcionalidade da Application classe, você deve implementar uma definição de aplicativo. Uma definição de aplicativo WPF é uma classe que deriva de Application e é configurada com uma configuração especial do MSBuild.

Implementando uma definição de aplicativo

Uma definição típica de aplicativo WPF é implementada usando marcação e "code-behind". Isso permite que você use a marcação para definir declarativamente as propriedades do aplicativo, os recursos e os eventos de registro, ao mesmo tempo em que manipula eventos e implementa o comportamento específico do aplicativo no code-behind.

O exemplo a seguir mostra como implementar uma definição de aplicativo usando tanto a marcação quanto o 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

Para permitir que um arquivo de marcação e um arquivo code-behind funcionem juntos, o seguinte precisa acontecer:

  • Na marcação, o Application elemento deve incluir o x:Class atributo. Quando o aplicativo é criado, a existência de x:Class no arquivo de marcação faz com que o MSBuild crie uma classe partial que deriva de Application com o nome especificado pelo atributo x:Class. Isso requer a adição de uma declaração de namespace XML para o esquema XAML (xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml").

  • No code-behind, a classe deve ser uma partial classe com o mesmo nome especificado pelo x:Class atributo na marcação e deve derivar de Application. Isso permite que o arquivo code-behind seja associado à partial classe que é gerada para o arquivo de marcação quando o aplicativo é criado (consulte Como criar um aplicativo WPF).

Observação

Quando você cria um novo projeto de aplicativo WPF ou um projeto de aplicativo WPF Browser no Visual Studio, uma definição de aplicativo é incluída por padrão e é definida usando tanto marcação quanto code-behind.

Esse código é o mínimo necessário para implementar uma definição de aplicativo. No entanto, uma configuração adicional do MSBuild precisa ser feita para a definição do aplicativo antes de compilar e executar o aplicativo.

Configurando a definição de aplicativo para MSBuild

Aplicativos autônomos e XBAPs (aplicativos de navegador XAML) exigem a implementação de um determinado nível de infraestrutura antes que eles possam ser executados. A parte mais importante dessa infraestrutura é o ponto de entrada. Quando um aplicativo é iniciado por um usuário, o sistema operacional chama o ponto de entrada, que é uma função conhecida para iniciar aplicativos.

Aviso

Os XBAPs exigem que navegadores herdados operem, como o Internet Explorer e versões antigas do Firefox. Esses navegadores mais antigos geralmente não têm suporte no Windows 10 e no Windows 11. Os navegadores modernos não dão mais suporte à tecnologia necessária para aplicativos XBAP devido a riscos de segurança. Plug-ins que habilitam XBAPs não têm mais suporte. Para obter mais informações, consulte Perguntas frequentes sobre oXBAP (aplicativos hospedados por navegador) do WPF.

Tradicionalmente, os desenvolvedores precisam escrever alguns ou todos esses códigos para si mesmos, dependendo da tecnologia. No entanto, o WPF gera esse código para você quando o arquivo de marcação da definição do aplicativo é configurado como um item do MSBuild ApplicationDefinition , conforme mostrado no seguinte arquivo de projeto do MSBuild:

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

Como o arquivo code-behind contém código, ele é marcado como um item MSBuild Compile , como é normal.

A aplicação dessas configurações do MSBuild para os arquivos de marcação e code-behind de uma definição de aplicativo faz com que o MSBuild gere código como o seguinte:

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

O código resultante aumenta a definição do aplicativo com código de infraestrutura adicional, que inclui o método Mainde ponto de entrada. O STAThreadAttribute atributo é aplicado ao Main método para indicar que o thread principal da interface do usuário para o aplicativo WPF é um thread STA, que é necessário para aplicativos WPF. Quando chamado, Main cria uma nova instância de App antes de chamar o método InitializeComponent para registrar os eventos e definir as propriedades que são implementadas na marcação. Como InitializeComponent é gerado para você, você não precisa chamar InitializeComponent explicitamente de uma definição de aplicativo como você faz para Page e Window implementações. Por fim, o Run método é chamado para iniciar o aplicativo.

Obtendo o aplicativo atual

Como a funcionalidade da Application classe é compartilhada em um aplicativo, pode haver apenas uma instância da Application classe por AppDomain. Para impor isso, a Application classe é implementada como uma classe singleton (consulte Implementando Singleton em C#), que cria uma única instância de si mesma e fornece acesso compartilhado a ela com a staticCurrent propriedade.

O código a seguir mostra como adquirir uma referência ao Application objeto para o atual AppDomain.

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

Current retorna uma referência a uma instância da Application classe. Se você quiser uma referência à sua Application classe derivada, deverá converter o valor da Current propriedade, conforme mostrado no exemplo a seguir.

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

Você pode inspecionar o valor de Current a qualquer ponto no tempo de vida de um objeto Application. No entanto, você deve ter cuidado. Depois que a Application classe é instanciada, há um período durante o qual o estado do Application objeto é inconsistente. Durante esse período, Application está executando as várias tarefas de inicialização que são necessárias para que o código seja executado, incluindo estabelecer a infraestrutura do aplicativo, definir propriedades e registrar eventos. Se você tentar usar o Application objeto durante esse período, seu código poderá ter resultados inesperados, especialmente se depender das várias propriedades que estão sendo definidas Application .

Quando Application conclui seu trabalho de inicialização, seu tempo de vida realmente começa.

Tempo de vida do aplicativo

A duração de um aplicativo WPF é marcada por vários eventos que são gerados por Application para informar quando seu aplicativo foi iniciado, ativado, desativado e encerrado.

Tela inicial

A partir do .NET Framework 3.5 SP1, você pode especificar uma imagem a ser usada em uma janela de inicialização ou tela inicial. A SplashScreen classe facilita a exibição de uma janela de inicialização enquanto o aplicativo está carregando. A SplashScreen janela é criada e mostrada antes Run de ser chamada. Para obter mais informações, consulte a Hora de Inicialização do Aplicativo e adicione uma tela inicial a um aplicativo WPF.

Iniciando um aplicativo

Depois que Run for chamado e o aplicativo for inicializado, o aplicativo estará pronto para ser executado. Este momento é indicado quando o evento Startup é gerado.

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>

Neste ponto do tempo de vida de um aplicativo, a coisa mais comum a fazer é mostrar uma interface do usuário.

Mostrando uma interface do usuário

A maioria dos aplicativos autônomos do Windows abre um Window quando eles começam a ser executados. O Startup manipulador de eventos é um local do qual você pode fazer isso, conforme demonstrado pelo código a seguir.

<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

Observação

O primeiro Window a ser instanciado em um aplicativo autônomo torna-se a janela principal do aplicativo por padrão. Esse Window objeto é referenciado pela Application.MainWindow propriedade. O valor da propriedade MainWindow poderá ser alterado programaticamente se uma janela diferente da primeira instanciada Window for a janela principal.

Quando um XBAP iniciar pela primeira vez, ele provavelmente navegará a um Page. Isso é mostrado no código a seguir.

<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

Se você manipular Startup para apenas abrir um Window ou navegar até um Page, poderá definir o atributo StartupUri na marcação.

O exemplo a seguir mostra como usar StartupUri em um aplicativo autônomo para abrir um Window.

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

O exemplo a seguir mostra como usar StartupUri de um XBAP para navegar até um Page.

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

Essa marcação tem o mesmo efeito do código anterior para abrir uma janela.

Observação

Para obter mais informações sobre navegação, consulte Visão geral da navegação.

Você precisa lidar com o Startup evento para abrir um Window caso precise instanciá-lo usando um construtor sem parâmetros ou precisar definir suas propriedades ou assinar seus eventos antes de mostrá-lo, ou você precisa processar quaisquer argumentos de linha de comando fornecidos quando o aplicativo foi iniciado.

Processando argumentos Command-Line

No Windows, aplicativos autônomos podem ser iniciados a partir de um prompt de comando ou da área de trabalho. Em ambos os casos, os argumentos de linha de comando podem ser passados para o aplicativo. O exemplo a seguir mostra um aplicativo que é iniciado com um único argumento de linha de comando, "/StartMinimized":

wpfapplication.exe /StartMinimized

Durante a inicialização do aplicativo, o WPF recupera os argumentos de linha de comando do sistema operacional e os passa para o Startup manipulador de eventos por meio da Args propriedade do StartupEventArgs parâmetro. Você pode recuperar e armazenar os argumentos de linha de comando usando código como o seguinte.

<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

O código manipula Startup para verificar se o argumento de linha de comando /StartMinimized foi fornecido; nesse caso, ele abre a janela principal com um WindowState de Minimized. Observe que, como a propriedade WindowState deve ser definida de forma programática, o elemento principal Window deve ser aberto explicitamente no código.

Os XBAPs não podem recuperar e processar argumentos de linha de comando porque são iniciados usando a implantação do ClickOnce (consulte Implantando um aplicativo WPF). No entanto, eles podem recuperar e processar parâmetros de cadeia de caracteres de consulta das URLs usadas para iniciá-los.

Ativação e desativação do aplicativo

O Windows permite que os usuários alternem entre aplicativos. A maneira mais comum é usar a combinação de teclas ALT+TAB. Um aplicativo só pode ser alternado se tiver um Window visível que o usuário possa selecionar. A atualmente selecionada Window é a janela ativa (também conhecida como janela de primeiro plano) e é a que recebe a entrada do Window usuário. O aplicativo com a janela ativa é o aplicativo ativo (ou aplicativo em primeiro plano). Um aplicativo se torna o aplicativo ativo nas seguintes circunstâncias:

  • Ele é lançado e exibe um Window.

  • Um usuário alterna de outro aplicativo selecionando um Window no aplicativo.

Você pode detectar quando um aplicativo se torna ativo manipulando o Application.Activated evento.

Da mesma forma, um aplicativo pode ficar inativo nas seguintes circunstâncias:

  • Um usuário alterna para um outro aplicativo a partir do atual.

  • Quando o aplicativo é desligado.

Você pode detectar quando um aplicativo fica inativo manipulando o Application.Deactivated evento.

O código a seguir mostra como lidar com os Activated eventos e Deactivated determinar se um aplicativo está ativo.

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

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

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

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

Imports System.Windows

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

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

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

Window pode também ser ativado e desativado. Consulte Window.Activated e Window.Deactivated para obter mais informações.

Observação

Nem Application.Activated nem Application.Deactivated são gerados para XBAPs.

Desligamento do aplicativo

A vida útil de um aplicativo termina quando ele é desligado, o que pode ocorrer pelos seguintes motivos:

  • Um usuário fecha cada Window.

  • Um usuário fecha o principal Window.

  • Um usuário encerra a sessão do Windows fazendo logon ou desligando.

  • Uma condição específica do aplicativo foi atendida.

Para ajudá-lo a gerenciar o desligamento do aplicativo, Application fornece o Shutdown método, a ShutdownMode propriedade e os SessionEndingExit eventos.

Observação

Shutdown só pode ser chamado de aplicativos que têm UIPermission. Aplicativos WPF autônomos sempre têm essa permissão. No entanto, os XBAPs em execução na área de segurança de confiança parcial da zona da Internet não o fazem.

Modo de desligamento

A maioria dos aplicativos é desligada quando todas as janelas são fechadas ou quando a janela principal é fechada. Às vezes, no entanto, outras condições específicas do aplicativo podem determinar quando um aplicativo é desligado. Você pode especificar as condições sob as quais seu aplicativo será desligado definindo ShutdownMode com um dos seguintes ShutdownMode valores de enumeração:

O valor ShutdownMode padrão é OnLastWindowClose, o que significa que um aplicativo é desligado automaticamente quando a última janela do aplicativo é fechada pelo usuário. No entanto, se o aplicativo deve ser desligado quando a janela principal é fechada, o WPF faz isso automaticamente se você definir ShutdownMode como OnMainWindowClose. Isso é mostrado no exemplo a seguir.

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

Quando você tiver condições de desligamento específicas do aplicativo, você definirá ShutdownMode como OnExplicitShutdown. Nesse caso, é sua responsabilidade desligar um aplicativo chamando explicitamente o Shutdown método; caso contrário, seu aplicativo continuará em execução mesmo se todas as janelas estiverem fechadas. Observe que Shutdown é chamado implicitamente quando o ShutdownMode é OnLastWindowClose ou OnMainWindowClose.

Observação

ShutdownMode pode ser definido a partir de um XBAP, mas é ignorado; um XBAP sempre é encerrado quando se navega para fora dele em um navegador ou quando o navegador que hospeda o XBAP é fechado. Para obter mais informações, consulte Visão geral de navegação.

Término da sessão

As condições de desligamento descritas pela ShutdownMode propriedade são específicas para um aplicativo. Em alguns casos, porém, um aplicativo pode ser desligado como resultado de uma condição externa. A condição externa mais comum ocorre quando um usuário encerra a sessão do Windows pelas seguintes ações:

  • Desconectar

  • Desligar

  • Reiniciar

  • Hibernando

Para detectar quando uma sessão do Windows termina, você pode manipular o SessionEnding evento, conforme ilustrado no exemplo a seguir.

<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

Neste exemplo, o código inspeciona a ReasonSessionEnding propriedade para determinar como a sessão do Windows está sendo encerrada. Ele usa esse valor para exibir uma mensagem de confirmação para o usuário. Se o usuário não quiser que a sessão seja encerrada, o código definirá Cancel para true impedir que a sessão do Windows seja encerrada.

Observação

SessionEnding não é gerado para XBAPs.

Fechar

Quando um aplicativo é desligado, talvez seja necessário executar algum processamento final, como manter o estado do aplicativo. Para essas situações, você pode lidar com o Exit evento, como o App_Exit manipulador de eventos faz no exemplo a seguir. Ele é definido como um manipulador de eventos no arquivo App.xaml . Sua implementação é realçada nos arquivos App.xaml.cs e 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

Para obter o exemplo completo, consulte Persist and Restore Application-Scope Properties Across Application Sessions.

Exit pode ser tratado por aplicativos autônomos e XBAPs. Para XBAPs, Exit é gerado sob as seguintes circunstâncias:

  • Um XBAP é navegado para longe.

  • No Internet Explorer, quando a guia que hospeda o XBAP é fechada,

  • Quando o navegador é fechado.

Código de Saída

Os aplicativos são iniciados principalmente pelo sistema operacional em resposta a uma solicitação de usuário. No entanto, um aplicativo pode ser iniciado por outro aplicativo para executar alguma tarefa específica. Quando o aplicativo iniciado é desligado, o aplicativo de inicialização pode querer saber a condição sob a qual o aplicativo iniciado foi desligado. Nessas situações, o Windows permite que os aplicativos retornem um código de saída do aplicativo no desligamento. Por padrão, os aplicativos WPF retornam um valor de código de saída de 0.

Observação

Ao depurar no Visual Studio, o código de saída do aplicativo é exibido na janela Saída quando o aplicativo é encerrado, em uma mensagem semelhante à seguinte:

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

Abra a janela Saída clicando em Saída no menu Exibir .

Para alterar o código de saída, você pode chamar a Shutdown(Int32) sobrecarga, que aceita um argumento inteiro para ser o código de saída:

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

Você pode detectar o valor do código de saída e alterá-lo manipulando o Exit evento. O manipulador de eventos Exit recebe um ExitEventArgs que fornece acesso ao código de saída através da propriedade ApplicationExitCode. Para obter mais informações, consulte Exit.

Observação

Você pode definir o código de saída em aplicativos autônomos e XBAPs. No entanto, o valor do código de saída é ignorado para XBAPs.

Exceções sem tratamento

Às vezes, um aplicativo pode ser desligado em condições anormais, como quando uma exceção inesperada é gerada. Nesse caso, o aplicativo pode não ter o código para detectar e processar a exceção. Esse tipo de exceção é uma exceção sem tratamento; uma notificação semelhante à mostrada na figura a seguir é exibida antes do aplicativo ser fechado.

Captura de tela que mostra uma notificação de exceção sem tratamento.

Do ponto de vista da experiência do usuário, é melhor para um aplicativo evitar esse comportamento padrão fazendo alguns ou todos os seguintes procedimentos:

  • Exibindo informações amigáveis ao usuário.

  • Tentando manter um aplicativo em execução.

  • Gravando informações de exceção detalhadas e amigáveis para o desenvolvedor no log de eventos do Windows.

A implementação desse suporte depende de ser capaz de detectar exceções sem tratamento, que é para o que o DispatcherUnhandledException evento é gerado.

<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

O DispatcherUnhandledException manipulador de eventos é passado um DispatcherUnhandledExceptionEventArgs parâmetro que contém informações contextuais sobre a exceção sem tratamento, incluindo a própria exceção (DispatcherUnhandledExceptionEventArgs.Exception). Você pode usar essas informações para determinar como lidar com a exceção.

Ao manipular DispatcherUnhandledException, você deve definir a DispatcherUnhandledExceptionEventArgs.Handled propriedade como true; caso contrário, o WPF ainda considera a exceção sem tratamento e reverte para o comportamento padrão descrito anteriormente. Se uma exceção sem tratamento for lançada e o evento DispatcherUnhandledException não for tratado, ou se o evento for tratado mas Handled estiver definido como false, o aplicativo se desligará imediatamente. Além disso, nenhum outro Application evento é gerado. Consequentemente, você precisará lidar DispatcherUnhandledException se o aplicativo tiver um código que deve ser executado antes que o aplicativo seja desligado.

Embora um aplicativo possa ser desligado como resultado de uma exceção sem tratamento, um aplicativo geralmente é desligado em resposta a uma solicitação de usuário, conforme discutido na próxima seção.

Eventos de tempo de vida do aplicativo

Aplicativos autônomos e XBAPs não têm exatamente o mesmo tempo de vida. A figura a seguir ilustra os principais eventos no tempo de vida de um aplicativo autônomo e mostra a sequência na qual eles são gerados.

Aplicativo Autônomo - Eventos do Objeto de Aplicativo

Da mesma forma, a figura a seguir ilustra os principais eventos no tempo de vida de um XBAP e mostra a sequência em que eles ocorrem.

XBAP – Eventos de objeto de aplicativo

Consulte também