Visão geral do gerenciamento de aplicativos
Todos os aplicativos tendem a compartilhar um conjunto comum de funcionalidades que se aplicam à implementação e ao gerenciamento do aplicativo. Este tópico fornece uma visão geral da funcionalidade na Application classe para criar e gerenciar aplicativos.
a classe do aplicativo
No WPF, a funcionalidade comum no escopo do aplicativo é encapsulada Application na classe. A Application classe inclui a seguinte funcionalidade:
Acompanhamento e interação com o tempo de vida do aplicativo.
Recuperar e processar parâmetros de linha de comando.
Detecção e resposta a exceções sem tratamento.
Compartilhar recursos e propriedades no escopo do aplicativo.
Gerenciamento de janelas de aplicativos autônomos.
Acompanhamento e gerenciamento da navegação.
Como realizar tarefas comuns usando a classe do aplicativo
Se você não estiver interessado em todos os detalhes da Application aula, a tabela a seguir lista algumas das tarefas comuns e Application como realizá-las. Ao exibir a API e os tópicos relacionados, você pode encontrar mais informações e o 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 do WPF. |
Iniciar um aplicativo | Use o método Application.Run. |
Parar um aplicativo | Use o Shutdown método do Application.Current objeto. |
Obter os 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 manipulador de Application.Exit eventos ou chame o Shutdown método e passe um inteiro. |
Detectar e responder a exceções sem tratamento | Manipule o DispatcherUnhandledException evento. |
Obter e definir recursos no escopo do aplicativo | Use a propriedade Application.Resources. |
Usar um dicionário de recursos no escopo do aplicativo | Consulte Usar um dicionário de recursos no escopo do aplicativo. |
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 no escopo do aplicativo em sessões de aplicativo. |
Gerencie arquivos de dados que não são de código, incluindo arquivos de recursos, arquivos de conteúdo e arquivos do site de origem. | Consulte Arquivos de recursos, de conteúdo e de dados de aplicativos do WPF. |
Gerenciar janelas em aplicativos autônomos | Consulte Visão geral do WPF do Windows. |
Acompanhar e gerenciar a navegação | Consulte Visão geral da navegação. |
A definição de aplicativo
Para utilizar a Application funcionalidade da classe, você deve implementar uma definição de aplicativo. Uma definição de aplicativo WPF é uma classe que deriva e é configurada com uma configuração especial do Application MSBuild.
Implementando uma definição de aplicativo
Uma definição típica de aplicativo WPF é implementada usando marcação e code-behind. Isso permite usar a marcação para definir de forma declarativa propriedades de aplicativo e recursos e registrar eventos durante a manipulação de eventos e a implementação de um comportamento específico ao aplicativo no code-behind.
O seguinte exemplo mostra como implementar uma definição de aplicativo usando a marcação e 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 o arquivo code-behind funcionem juntos, deve ocorrer o seguinte:
Na marcação, o elemento
Application
deve incluir o atributox:Class
. Quando o aplicativo é criado, a existência de no arquivo dex:Class
marcação faz com que o MSBuild crie umapartial
classe que deriva e Application tem o nome especificado pelox:Class
atributo. Isso exige a adição de uma declaração de namespace de 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 pelox:Class
atributo na marcação e deve derivar de Application. Isso permite que o arquivo code-behind seja associado àpartial
classe gerada para o arquivo de marcação quando o aplicativo é criado (consulte Criando um aplicativo WPF).
Observação
Quando você cria um novo projeto de aplicativo WPF ou projeto de aplicativo de navegador WPF usando o Visual Studio, uma definição de aplicativo é incluída por padrão e é definida usando marcação e 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 na definição do aplicativo antes de compilar e executar o aplicativo.
Configurando a definição de aplicativo no MSBuild
Aplicativos autônomos e XBAPs (aplicativos de navegador XAML) exigem a implementação de um determinado nível de infraestrutura antes de serem 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 bem conhecida para a inicialização de aplicativos.
Aviso
Os XBAPs exigem navegadores legados para operar, como o Internet Explorer e versões antigas do Firefox. Esses navegadores mais antigos geralmente não são compatíveis com Windows 10 e Windows 11. Os navegadores modernos não suportam mais a tecnologia necessária para aplicativos XBAP devido a riscos de segurança. Plug-ins que habilitam XBAPs não são mais suportados. Para obter mais informações, consulte Perguntas frequentes sobre aplicativos hospedados no navegador do WPF (XBAP).
Tradicionalmente, os desenvolvedores precisam escrever parte ou todo esse código por conta própria, 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 do MSBuild Compile
, como é normal.
A aplicação dessas configurações do MSBuild aos 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 de aplicativo com um código de infraestrutura adicional, que inclui o método de ponto de entrada Main
. 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 antes de App
chamar o InitializeComponent
método para registrar os eventos e definir as propriedades implementadas na marcação. Como InitializeComponent
é gerado para você, você não precisa chamar InitializeComponent
explicitamente de uma definição de aplicativo como faz para Page implementações e Window . Por fim, o Run método é chamado para iniciar o aplicativo.
Obtendo o aplicativo atual
Como a Application funcionalidade da classe é compartilhada em um aplicativo, pode haver apenas uma instância da Application classe por AppDomain. Para impor isso, a classe é implementada Application 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 static
Current propriedade.
O código a seguir mostra como adquirir uma referência ao Application objeto para o 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 Current valor da 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 em qualquer ponto do tempo de vida de um Application objeto. No entanto, é necessário ter cuidado. Depois que a Application classe é instanciada, há um período durante o qual o Application estado do objeto é inconsistente. Durante esse período, Application está executando as várias tarefas de inicialização exigidas pela execução do código, incluindo o estabelecimento da infraestrutura do aplicativo, a configuração de propriedades e o registro de 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 Application propriedades que estão sendo definidas.
Quando Application conclui seu trabalho de inicialização, seu tempo de vida realmente começa.
Tempo de vida do aplicativo
O tempo de vida de um aplicativo WPF é marcado por vários eventos que são gerados para Application que você saiba quando seu aplicativo foi iniciado, foi ativado e desativado e foi desligado.
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á sendo carregado. A SplashScreen janela é criada e mostrada antes de Run ser chamada. Para obter mais informações, consulte Tempo de inicialização do aplicativo e Adicionar uma tela inicial a um aplicativo do WPF.
Iniciando um aplicativo
Depois de Run ser chamado e o aplicativo ser inicializado, o aplicativo estará pronto para ser executado. Este momento é significado quando o Startup evento é levantado:
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 começa a ser executado. 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 Application.MainWindow pela propriedade. O valor da MainWindow propriedade pode ser alterado programaticamente se uma janela diferente da primeira instanciada Window deve ser a janela principal.
Quando um XBAP é iniciado pela primeira vez, ele provavelmente navegará para um Pagearquivo . Isso será 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 apenas abrir um Window ou navegar até um Page, poderá definir o StartupUri
atributo na marcação.
O exemplo a seguir mostra como usar o StartupUri de 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 um XBAP para navegar até um Pagearquivo .
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
StartupUri="HomePage.xaml" />
Essa marcação tem o mesmo efeito que o 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 manipular o Startup evento para abrir um Window se precisar instanciá-lo usando um construtor sem parâmetros, ou se precisar definir suas propriedades ou assinar seus eventos antes de mostrá-lo, ou se precisar processar quaisquer argumentos de linha de comando que foram fornecidos quando o aplicativo foi iniciado.
Processando argumentos de linha de comando
No Windows, os 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 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. É possível recuperar e armazenar os argumentos de linha de comando usando um código semelhante ao mostrado 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)
{
// 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; em caso afirmativo, ele abre a janela principal com um WindowState .Minimized Observe que, como a WindowState propriedade deve ser definida programaticamente, o main 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 de URLs usadas para iniciá-los.
Ativação e desativação de aplicativos
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 visível Window que um usuário possa selecionar. A selecionada Window no momento é a janela ativa (também conhecida como janela de primeiro plano) e é a que recebe a Window entrada do usuário. O aplicativo com a janela ativa é o aplicativo ativo (ou o aplicativo em primeiro plano). Um aplicativo se torna o aplicativo ativo nas seguintes circunstâncias:
Ele é lançado e mostra um Windowdomínio .
Um usuário alterna de outro aplicativo selecionando a Window no aplicativo.
Você pode detectar quando um aplicativo se torna ativo manipulando o Application.Activated evento.
Da mesma forma, um aplicativo pode se tornar inativo nas seguintes circunstâncias:
Um usuário muda para outro aplicativo do aplicativo atual.
Quando o aplicativo é desligado.
Você pode detectar quando um aplicativo se torna inativo manipulando o Application.Deactivated evento.
O código a seguir mostra como manipular os Activated eventos and Deactivated para 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
A Window também pode ser ativado e desativado. Consulte Window.Activated e Window.Deactivated para obter mais informações.
Observação
Nem Application.Activated nem Application.Deactivated é gerado para XBAPs.
Desligamento do aplicativo
A vida de um aplicativo termina quando ele é desligado, o que pode ocorrer pelos seguintes motivos:
Um usuário fecha todos os Windowarquivos .
Um usuário fecha o arquivo .Window
Um usuário encerra a sessão do Windows fazendo logoff ou desligando.
Uma condição específica ao aplicativo foi atendida.
Para ajudá-lo a gerenciar o desligamento do aplicativo, Application fornece o Shutdown método, a ShutdownMode propriedade e os SessionEnding eventos and Exit .
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 restrita de segurança de confiança parcial da zona da Internet não.
Modo de desligamento
A maioria dos aplicativos é desligada quando todas as janelas são fechadas ou quando a janela principal é fechada. No entanto, às vezes, outras condições específicas ao aplicativo podem determinar quando um aplicativo é desligado. Você pode especificar as condições sob as quais seu aplicativo será desligado definindo ShutdownMode um dos seguintes ShutdownMode valores de enumeração:
O valor padrão de ShutdownMode é OnLastWindowClose, o que significa que um aplicativo é desligado automaticamente quando a última janela do aplicativo é fechada pelo usuário. No entanto, se o aplicativo for desligado quando a janela principal for fechada, o WPF fará 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ê tem condições de desligamento específicas do aplicativo, defina 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 é ou OnLastWindowClose .OnMainWindowClose
Observação
ShutdownMode pode ser definido a partir de um XBAP, mas é ignorado; um XBAP é sempre desligado quando é navegado para fora de um navegador ou quando o navegador que hospeda o XBAP é fechado. Para obter mais informações, consulte Visão geral de navegação.
Encerramento da sessão
As condições de desligamento descritas pela ShutdownMode propriedade são específicas de um aplicativo. No entanto, em alguns casos, 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:
Logoff
Desligamento
Reinicialização
Hibernação
Para detectar quando uma sessão do Windows termina, você pode manipular o evento, conforme ilustrado SessionEnding 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á terminando. 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 termine, o código será definido Cancel como true
para impedir que a sessão do Windows seja encerrada.
Observação
SessionEnding não é gerado para XBAPs.
Exit
Quando um aplicativo é desligado, ele pode precisar executar algum processamento final, como persistir o estado do aplicativo. Para essas situações, você pode manipular 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 é destacada 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 Persistir e restaurar propriedades no escopo do aplicativo em sessões de aplicativo.
Exit podem ser manipulados por aplicativos autônomos e XBAPs. Para XBAPs, Exit é gerado quando nas 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
Na maioria das vezes, os aplicativos são iniciados pelo sistema operacional em resposta a uma solicitação do usuário. No entanto, um aplicativo pode ser iniciado por outro aplicativo para executar uma tarefa específica. Quando o aplicativo iniciado é desligado, o aplicativo que o iniciou talvez deseje saber a condição na 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
Quando você depura do Visual Studio, o código de saída do aplicativo é exibido na janela Saída quando o aplicativo é desligado, 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 Exit manipulador de eventos é passado um ExitEventArgs que fornece acesso ao código de saída com a ApplicationExitCode propriedade. 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 não esperada é 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; é exibida uma notificação semelhante à mostrada na figura a seguir antes de o aplicativo ser fechado.
Da perspectiva da experiência do usuário, é melhor que um aplicativo evite esse comportamento padrão fazendo algumas ou todas as seguintes opções:
Exibição de informações amigáveis.
Tentativa de manter um aplicativo em execução.
Gravação de informações de exceção detalhadas e amigáveis ao desenvolvedor no log de eventos do Windows.
A implementação desse suporte depende da capacidade 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 recebe 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 tratar a exceção.
Ao manipular DispatcherUnhandledExceptiono , você deve definir a DispatcherUnhandledExceptionEventArgs.Handled propriedade como true
; caso contrário, o WPF ainda considera a exceção como sem tratamento e reverte para o comportamento padrão descrito anteriormente. Se uma exceção sem tratamento for gerada e o DispatcherUnhandledException evento não for manipulado ou o evento for manipulado e Handled definido como false
, o aplicativo será desligado imediatamente. Além disso, nenhum outro Application evento é levantado. Consequentemente, você precisa lidar DispatcherUnhandledException se seu aplicativo tem 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, geralmente, um aplicativo é desligado em resposta a uma solicitação do usuário, conforme abordado na próxima seção.
Eventos de Vida Útil 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 são acionados.
Da mesma forma, a figura a seguir ilustra os principais eventos no tempo de vida de um XBAP e mostra a sequência na qual eles são gerados.
Confira também
.NET Desktop feedback