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 classe Application para criar e gerenciar aplicativos.
A classe de aplicativo
No WPF, a funcionalidade comum do escopo do aplicativo é encapsulada na classe Application. A classe Application inclui a seguinte funcionalidade:
Rastreando e interagindo com o tempo de vida do aplicativo.
Recuperando e processando parâmetros de linha de comando.
Detetar e responder a exceções não tratadas.
Compartilhamento de propriedades e recursos do escopo do aplicativo.
Gerenciando janelas em aplicativos autônomos.
Acompanhamento e gestão da navegação.
Como executar tarefas comuns usando a classe de aplicativo
Se você não estiver interessado em todos os detalhes da classe Application, a tabela a seguir lista algumas das tarefas comuns para Application e como realizá-las. Ao visualizar 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 | Utilize a propriedade Application.Current. |
Adicionar uma tela de inicialização a um aplicativo | Consulte Adicionar uma tela inicial a um aplicativo WPF. |
Iniciar uma candidatura | Use o método Application.Run. |
Parar um aplicativo | Use o método Shutdown do objeto Application.Current. |
Obter argumentos da linha de comando | Manipule o evento Application.Startup e use a propriedade StartupEventArgs.Args. Para obter um exemplo, consulte o evento Application.Startup. |
Obter e definir o código de saída do aplicativo | Defina a propriedade ExitEventArgs.ApplicationExitCode no manipulador de eventos Application.Exit ou chame o método Shutdown e passe um inteiro. |
Detetar e responder a exceções não tratadas | Manipule o evento DispatcherUnhandledException. |
Obter e definir recursos com escopo de aplicação | Use a propriedade Application.Resources. |
Usar um dicionário de recursos do escopo do aplicativo | Consulte Use um dicionário de recursos Application-Scope. |
Obter e definir propriedades com escopo de aplicação | Use a propriedade Application.Properties. |
Obter e salvar o estado de um aplicativo | Consulte Persistir e restaurar propriedades de Application-Scope em sessões de aplicativos. |
Gerencie arquivos de dados não codificados, incluindo arquivos de recursos, arquivos de conteúdo e arquivos de site de origem. | Consulte Recursos, conteúdo e arquivos de dados da aplicação WPF. |
Gerenciar janelas em aplicativos autônomos | Consulte a Visão Geral do WPF para Windows . |
Rastreie e gerencie a navegação | Consulte Visão Geral da Navegação. |
A definição do aplicativo
Para utilizar a funcionalidade da classe Application, 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 propriedades do aplicativo, recursos e registrar eventos, enquanto 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 código de marcação e "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 trabalhem juntos, o seguinte precisa acontecer:
Na marcação, o elemento
Application
deve incluir o atributox:Class
. Quando o aplicativo é criado, a existência dex:Class
no arquivo de marcação faz com que o MSBuild crie uma classepartial
que deriva de Application e tem o nome especificado pelo atributox: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 classe
partial
com o mesmo nome especificado pelo atributox:Class
na marcação e deve derivar de Application. Isso permite que o arquivo code-behind seja associado à classepartial
que é gerada para o arquivo de marcação quando o aplicativo é criado (consulte Criando um aplicativo WPF).
Observação
Quando se cria um novo projeto de aplicação WPF ou projeto de aplicação de navegador WPF utilizando o Visual Studio, uma definição de aplicação é incluída por defeito e é definida através de marcação e código subjacente.
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 criar e executar o aplicativo.
Configurando a definição de aplicativo para MSBuild
Aplicativos autônomos e aplicativos de navegador XAML (XBAPs) exigem a implementação de um determinado nível de infraestrutura antes de poderem ser executados. A parte mais importante desta 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 iniciar aplicativos.
Advertência
Os XBAPs requerem navegadores herdados para funcionar, como o Internet Explorer e versões antigas do Firefox. Esses navegadores mais antigos geralmente não são suportados no Windows 10 e no 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 freqüentes sobre aplicativos hospedados no navegador WPF (XBAP).
Tradicionalmente, os desenvolvedores precisam escrever parte ou todo esse código 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 de ApplicationDefinition
do MSBuild, 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 de Compile
do MSBuild, 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 sua definição de aplicativo com código de infraestrutura adicional, que inclui o método de ponto de entrada Main
. O atributo STAThreadAttribute é aplicado ao método Main
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 explicitamente InitializeComponent
de uma definição de aplicativo, como faz para implementações Page e Window. Finalmente, o método Run é chamado para iniciar o aplicativo.
Obtendo o aplicativo atual
Como a funcionalidade da classe Application é compartilhada em um aplicativo, pode haver apenas uma instância da classe Application por AppDomain. Para impor isso, a classe Application é implementada como uma classe singleton (consulte Implementing Singleton in C#), que cria uma única instância de si mesma e fornece acesso compartilhado a ela com a propriedade static
Current.
O código a seguir mostra como adquirir uma referência ao objeto Application para o AppDomainatual.
// 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 classe Application. Se você quiser uma referência à sua classe derivada Application, deverá converter o valor da propriedade Current, 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 momento do tempo de vida de um objeto Application. No entanto, você deve ter cuidado. Depois que a classe Application é instanciada, há um período durante o qual o estado do objeto Application é 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 definição de propriedades e o registro de eventos. Se você tentar usar o objeto Application durante esse período, seu código pode ter resultados inesperados, especialmente se depender das várias propriedades Application que estão sendo definidas.
Quando Application conclui seu trabalho de inicialização, sua vida útil 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 por Application para que você saiba quando seu aplicativo foi iniciado, foi ativado e desativado e foi encerrado.
Ecrã 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 classe SplashScreen facilita a exibição de uma janela de inicialização enquanto o aplicativo está sendo carregado. A janela SplashScreen é criada e mostrada antes de Run ser chamada. Para obter mais informações, consulte Tempo de Inicialização da Aplicação e Adicionar uma Tela Inicial a uma Aplicação WPF.
Iniciando um aplicativo
Depois que Run é chamado e o aplicativo é inicializado, o aplicativo está pronto para ser executado. Este momento é significado quando o evento Startup é 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 de usuário
A maioria dos aplicativos autônomos do Windows abre um Window quando começam a ser executados. O manipulador de eventos Startup é um local a partir 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 objeto Window é referenciado pela propriedade Application.MainWindow. O valor da propriedade MainWindow pode ser alterado programaticamente para que uma janela, diferente da primeira instanciada Window, seja a janela principal.
Quando um XBAP é iniciado pela primeira vez, ele provavelmente navegará para 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 lidares com Startup apenas para abrir um Window ou navegar para um Page, podes definir o atributo StartupUri
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 de um XBAP para navegar até um Page.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
StartupUri="HomePage.xaml" />
Esta 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 evento Startup 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.
Processamento dos argumentos Command-Line
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 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 manipulador de eventos Startup por meio da propriedade Args do parâmetro StartupEventArgs. Você pode recuperar e armazenar os argumentos de linha de comando usando um 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 lida com Startup para verificar se o argumento de linha de comando /StartMinimized foi fornecido. Caso contrário, abre a janela principal com um(a) WindowState de Minimized. Observe que, como a propriedade WindowState deve ser definida programaticamente, o Window principal deve ser aberto explicitamente no código.
XBAPs não podem recuperar e processar argumentos de linha de comando porque eles 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 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 Window visível que um usuário possa selecionar. A Window selecionada atualmente é a janela ativa (também conhecida como janela de primeiro plano) e é a Window que recebe a entrada do usuário. O aplicativo com a janela ativa é o aplicativo ativo (ou aplicativo em primeiro plano). Um aplicativo torna-se o aplicativo ativo nas seguintes circunstâncias:
É lançado e mostra um Window.
Um utilizador muda de outra aplicação, selecionando um Window na aplicação.
Você pode detetar quando um aplicativo fica ativo manipulando o evento Application.Activated.
Da mesma forma, um aplicativo pode ficar inativo nas seguintes circunstâncias:
Um utilizador alterna para outra aplicação a partir da atual.
Quando o aplicativo é desligado.
Você pode detetar quando um aplicativo fica inativo manipulando o evento Application.Deactivated.
O código a seguir mostra como manipular os eventos Activated e 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
Um 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 são ativados para XBAPs.
Desligamento de aplicativos
A vida útil de um aplicativo termina quando ele é desligado, o que pode ocorrer pelos seguintes motivos:
Um usuário fecha todos os Window.
Um usuário fecha o Windowprincipal.
Um usuário termina a sessão do Windows fazendo logoff ou desligando.
Foi satisfeita uma condição específica da aplicação.
Para ajudá-lo a gerenciar o desligamento do aplicativo, o Application fornece o método Shutdown, a propriedade ShutdownMode e os eventos SessionEnding e Exit.
Observação
Shutdown só pode ser chamado a partir de aplicativos que tenham UIPermission. Aplicativos WPF autônomos sempre têm essa permissão. No entanto, XBAPs em execução na sandbox de segurança com confiança parcial da zona da Internet não.
Modo de Encerramento
A maioria das aplicações encerra quando todas as janelas estão fechadas ou quando a janela principal está 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á encerrado definindo ShutdownMode com um dos seguintes valores de enumeração ShutdownMode:
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 seu aplicativo deve ser desligado quando a janela principal é fechada, o WPF faz isso automaticamente se você definir ShutdownMode para 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, defina ShutdownMode como OnExplicitShutdown. Neste caso, é sua responsabilidade encerrar um aplicativo chamando explicitamente o método Shutdown; 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 fechado quando a navegação é feita para fora de um navegador ou quando o navegador que hospeda o XBAP é fechado. Para obter mais informações, consulte Visão geral da navegação .
Encerramento da sessão
As condições de desligamento descritas pela propriedade ShutdownMode são específicas de um aplicativo. Em alguns casos, porém, um aplicativo pode ser encerrado como resultado de uma condição externa. A condição externa mais comum ocorre quando um usuário termina a sessão do Windows pelas seguintes ações:
Terminar sessão
Encerramento
Reinício
Hibernação
Para detetar quando uma sessão do Windows termina, você pode manipular o evento SessionEnding, 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 propriedade ReasonSessionEnding 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 define Cancel para true
para impedir que a sessão do Windows termine.
Observação
SessionEnding não é gerado para XBAPs.
Sair
Quando um aplicativo é desligado, talvez seja necessário executar algum processamento final, como o estado persistente do aplicativo. Para essas situações, você pode manipular o evento Exit, como o manipulador de eventos App_Exit
faz no exemplo a seguir. Ele é definido como um manipulador de eventos no arquivo App.xaml
<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 manipulado por aplicações independentes e XBAPs. Para XBAPs, Exit é gerado nas seguintes circunstâncias:
Um XBAP é navegado para longe.
No Internet Explorer, quando o separador que está a alojar o XBAP é fechado.
Quando o navegador é fechado.
Código de saída
Os aplicativos são iniciados principalmente pelo sistema operacional em resposta a uma solicitação do 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 é 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 a partir do Visual Studio, o código de saída da aplicação é apresentado na janela Saída quando a aplicação termina, numa mensagem semelhante à seguinte:
The program '[5340] AWPFApp.vshost.exe: Managed' has exited with code 0 (0x0).
Abra a janela Output clicando em Output no menu View.
Para alterar o código de saída, você pode chamar a sobrecarga Shutdown(Int32), que aceita um argumento inteiro como sendo 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 detetar o valor do código de saída e alterá-lo manipulando o evento Exit. O manipulador de eventos Exit recebe um ExitEventArgs que fornece acesso ao código de saída com a 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 não tratadas
Às vezes, um aplicativo pode ser desligado em condições anormais, como quando uma exceção inesperada é lançada. Nesse caso, o aplicativo pode não ter o código para detetar e processar a exceção. Este tipo de exceção é uma exceção não tratada; Uma notificação semelhante à mostrada na figura a seguir é exibida antes do fechamento do aplicativo.
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:
Exibição de informações fáceis de usar.
Tentando manter um aplicativo em execução.
Gravação de informações de exceção detalhadas e amigáveis para desenvolvedores no log de eventos do Windows.
A implementação desse suporte depende da capacidade de detetar exceções não tratadas, que é para o que o evento DispatcherUnhandledException é 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 manipulador de eventos DispatcherUnhandledException recebe um parâmetro DispatcherUnhandledExceptionEventArgs que contém informações contextuais sobre a exceção não tratada, incluindo a própria exceção (DispatcherUnhandledExceptionEventArgs.Exception). Você pode usar essas informações para determinar como lidar com a exceção.
Ao lidar com DispatcherUnhandledException, você deve definir a propriedade DispatcherUnhandledExceptionEventArgs.Handled como true
; caso contrário, o WPF ainda considera a exceção como não tratada e reverte para o comportamento padrão descrito anteriormente. Se uma exceção não tratada for gerada e o evento DispatcherUnhandledException não for manipulado, ou se o evento for manipulado e Handled estiver definido como false
, o aplicativo será desligado imediatamente. Além disso, não são gerados outros eventos Application. Consequentemente, você precisa lidar com DispatcherUnhandledException se seu aplicativo tiver código que deve ser executado antes que o aplicativo seja desligado.
Embora um aplicativo possa ser desligado como resultado de uma exceção não tratada, um aplicativo geralmente é desligado em resposta a uma solicitação do 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 a mesma vida útil. 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.
De igual forma, a figura a seguir ilustra os principais eventos no ciclo de vida de um XBAP e mostra a sequência em que eles ocorrem.
Ver também
- Application
- Visão Geral do Windows WPF
- Visão geral da navegação
- Recursos, Conteúdo e Arquivos de Dados de Aplicação WPF
- Pack URIs no WPF
- Modelo de aplicativo : tópicos de instruções
- de Desenvolvimento de Aplicações
.NET Desktop feedback