應用程式管理概觀

所有應用程式通常會共用一組適用於應用程式實作和管理的通用功能。 本主題提供 類別中 Application 用來建立和管理應用程式的功能概觀。

應用程式類別

在 WPF 中,常見的應用程式範圍功能會封裝在 類別中 Application 。 類別 Application 包含下列功能:

  • 追蹤應用程式存留期並與其互動。

  • 擷取及處理命令列參數。

  • 偵測及回應未處理的例外狀況。

  • 共用應用程式範圍的屬性和 資源。

  • 管理獨立應用程式中的視窗。

  • 追蹤及管理瀏覽。

如何使用 Application 類別執行一般工作

如果您對 類別的所有詳細數據 Application 不感興趣,下表列出一些常見的工作 Application ,以及如何完成這些工作。 您可以檢視相關的 API 和主題,來尋找詳細資訊和範例程式碼。

Task 方法
取得代表目前應用程式的物件 請使用 Application.Current 屬性。
將啟動畫面新增至應用程式 請參閱將啟動顯示畫面新增至 WPF 應用程式
啟動應用程式 使用 Application.Run 方法。
停止應用程式 Shutdown使用物件的方法Application.Current
從命令列取得引數 Application.Startup處理 事件並使用 StartupEventArgs.Args 屬性。 如需範例,請參閱 Application.Startup 事件。
取得及設定應用程式結束代碼 ExitEventArgs.ApplicationExitCode在事件處理程式中Application.Exit設定 屬性,或呼叫 Shutdown 方法並傳入整數。
偵測及回應未處理的例外狀況 DispatcherUnhandledException處理事件。
取得及設定應用程式範圍的資源 請使用 Application.Resources 屬性。
使用應用程式範圍的資源字典 請參閱使用應用程式範圍的資源字典
取得及設定應用程式範圍的屬性 請使用 Application.Properties 屬性。
取得及儲存應用程式的狀態 請參閱跨應用程式工作階段保存和還原應用程式範圍的屬性
管理非程式碼資料檔案,包括資源檔、內容檔案和來源網站檔案。 請參閱 WPF 應用程式資源、內容和資料檔案
管理獨立應用程式中的視窗 請參閱 WPF 視窗概觀
追蹤及管理瀏覽 請參閱 導覽概觀

應用程式定義

若要利用 類別的功能 Application ,您必須實作應用程式定義。 WPF 應用程式定義是衍生自 Application 的類別,並使用特殊的 MSBuild 設定進行設定。

實作應用程式定義

典型的 WPF 應用程式定義會使用標記和程式代碼後置來實作。 這可讓您使用標記,以宣告方式設定應用程式屬性、資源和註冊事件,同時在程式碼後置中,處理事件及實作應用程式特定行為。

下列範例示範如何使用標記和程式碼後置,來實作應用程式定義:

<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

若要搭配使用標記檔案和程式碼後置檔案,下列情況必須成立:

  • 在標記中,Application 元素必須包含 x:Class 屬性。 建置應用程式時,標記檔案中是否存在 x:Class 會導致 MSBuild 建立 partial 衍生自 Application 的類別,並具有 屬性所 x:Class 指定的名稱。 這需要新增 XAML 結構描述的 XML 命名空間宣告 (xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml")。

  • 在程式代碼後置中,類別必須是 partial 具有標記中 屬性所指定之相同名稱的 x:Class 類別,而且必須衍生自 Application。 這可讓程式代碼後置檔案與 partial 建置應用程式時為標記檔案產生的類別產生關聯(請參閱 建置 WPF 應用程式)。

注意

當您使用 Visual Studio 建立新的 WPF 應用程式專案或 WPF 瀏覽器應用程式專案時,預設會包含應用程式定義,並使用標記和程式碼後置來定義。

此程式碼是實作應用程式定義的最低需求。 不過,在建置和執行應用程式之前,必須先對應用程式定義進行額外的 MSBuild 組態。

設定 MSBuild 的應用程式定義

獨立應用程式和 XAML 瀏覽器應用程式 (XBAP) 需要實作特定層級的基礎結構,才能執行。 此基礎結構的最重要部分是進入點。 當使用者啟動應用程式時,作業系統會呼叫進入點,這是用於啟動應用程式的已知函式。

警告

XBAP 需要舊版瀏覽器才能運作,例如 Internet Explorer 和 Firefox。 Windows 10 和 Windows 11 通常不支援這些舊版瀏覽器版本。 由於安全性風險,新式瀏覽器不再支援 XBAP 應用程式所需的技術。 不再支援啟用 XBAP 的外掛程式。

傳統上,開發人員必須自行撰寫這段程式碼的一部分或全部 (視使用技術而定)。 不過,WPF 會在應用程式定義的標記檔設定為 MSBuild 專案時為您產生此程式代碼,如下列 MSBuild ApplicationDefinition 專案檔所示:

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

因為程式代碼後置檔案包含程序代碼,所以它會標示為 MSBuild Compile 專案,如同正常。

這些 MSBuild 組態的套用至應用程式定義的標記和程式代碼後置檔案,會導致 MSBuild 產生如下的程式代碼:

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

產生的程式碼會透過額外的基礎結構程式碼來增強您的應用程式,其中包含進入點方法 Main。 屬性 STAThreadAttribute 會套用至 Main 方法,指出 WPF 應用程式的主要 UI 線程是 WPF 應用程式所需的 STA 線程。 呼叫 時, Main 先建立 的新實例 App ,再呼叫 InitializeComponent 方法來註冊事件,並設定在標記中實作的屬性。 因為 InitializeComponent 是為您產生的,因此您不需要像針對 PageWindow 實作一樣,明確地從應用程式定義呼叫 InitializeComponent 。 最後, Run 呼叫 方法以啟動應用程式。

取得目前的應用程式

因為類別的功能Application會跨應用程序共用,因此每個 AppDomain類別只能有一個實例Application。 若要強制執行這項作業,類別 Application 會實作為單一類別(請參閱 在 C# 中實作 Singleton),這會建立本身的單一實例,並使用 屬性提供其共用存取 staticCurrent 權。

下列程式代碼示範如何取得目前 AppDomain對象的參考Application

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

Current 傳回 類別實例的 Application 參考。 如果您想要衍生類別的ApplicationCurrent參考,您必須轉換 屬性的值,如下列範例所示。

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

您可以在物件的存留期Application中的任何時間點檢查 的值Current。 不過,您應該要小心。 具現化 類別 Application 之後,會有一段期間,物件的狀態 Application 不一致。 在此期間, Application 會執行程式代碼執行所需的各種初始化工作,包括建立應用程式基礎結構、設定屬性和註冊事件。 如果您在此期間嘗試使用 Application 物件,您的程式代碼可能會有非預期的結果,特別是如果它相依於所設定的各種 Application 屬性。

完成初始化工作時 Application ,其存留期就會真正開始。

應用程式存留期

WPF 應用程式的存留期會以數個事件標示,這些事件是由 引發 Application ,讓您知道應用程式何時啟動、已啟動和停用,並已關閉。

啟動顯示畫面

從 .NET Framework 3.5 SP1 開始,您可以指定要用於啟動視窗或 啟動顯示畫面的影像。 類別 SplashScreen 可讓您輕鬆地在載入應用程式時顯示啟動視窗。 視窗 SplashScreen 會在呼叫之前 Run 建立並顯示。 如需詳細資訊,請參閱應用程式啟動時間將啟動顯示畫面新增至 WPF 應用程式

啟動應用程式

呼叫 並初始化應用程式之後 Run ,應用程式即可執行。 引發事件時 Startup ,表示此刻:

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>

在應用程式的存留期內,最常見的動作是顯示UI。

顯示使用者介面

大部分的獨立 Windows 應用程式會在開始執行時開啟 WindowStartup事件處理程式是一個您可以從中執行此動作的位置,如下列程式代碼所示。

<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

注意

第一個 Window 在獨立應用程式中具現化的應用程式預設會變成主要應用程式視窗。 屬性會Application.MainWindow參考這個Window物件。 如果與第一個具現化Window視窗不同的視窗應該是主視窗,則可以以程式設計方式變更 屬性的值MainWindow

當 XBAP 第一次啟動時,它很可能會巡覽至 Page。 如下列程式碼所示。

<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

如果您只處理 Startup 以開啟 Window 或 巡覽至 Page,您可以改為在標記中設定 StartupUri 屬性。

下列範例示範如何使用 StartupUri 獨立應用程式的 來開啟 Window

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

下列範例示範如何使用 StartupUri XBAP 巡覽至 Page

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

此標記與前述用來開啟視窗的程式碼有相同的效果。

注意

如需瀏覽的詳細資訊,請參閱瀏覽概觀

如果您需要使用非無參數建構函式來具現化事件Window,或需要在顯示事件之前設定其屬性或訂閱其事件,或是需要處理啟動應用程式時提供的任何命令行自變數,您需要處理Startup事件。

處理命令列引數

在 Windows 中,獨立應用程式可以從命令提示字元或桌面啟動。 在這兩種情況下,都會將命令列引數傳遞至應用程式。 下列範例顯示以單一命令列引數 "/StartMinimized" 啟動的應用程式:

wpfapplication.exe /StartMinimized

在應用程式初始化期間,WPF 會從操作系統擷取命令行自變數,並透過 Args 參數的 StartupEventArgs 屬性將它們傳遞至Startup事件處理程式。 您可以使用如下的程式碼擷取及儲存命令列引數。

<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

程式代碼會處理 Startup 以檢查是否 提供 /StartMinimized 命令行自變數;如果是的話,它會開啟主視窗,且具有 WindowStateMinimized。 請注意,由於 WindowState 屬性必須以程序設計方式設定,因此必須在程式代碼中明確開啟main Window

XBAP 無法擷取及處理命令行自變數,因為它們是使用 ClickOnce 部署啟動的(請參閱 部署 WPF 應用程式)。 不過,它們可以透過用來啟動的 URL 擷取及處理查詢字串參數。

應用程式啟用和停用

Windows 可讓使用者在應用程式之間切換。 最常見的做法是使用 ALT+TAB 按鍵組合。 只有在應用程式有使用者可選擇的可見 Window 狀態時,才能切換至 。 目前選取Window的是活動視窗(也稱為前景視窗),而且是Window接收使用者輸入的 。 具有使用中視窗的應用程式是「使用中應用程式」 (或「前景應用程式」)。 在下列情況中,應用程式會變成使用中應用程式:

  • 開啟並顯示 Window

  • 使用者在應用程式中選取 ,以從另一 Window 個應用程式切換。

您可以藉由處理事件來偵測應用程式何時變成作用中 Application.Activated

同樣地,在下列情況中,應用程式會變成非使用中:

  • 使用者從目前的應用程式切換至另一個應用程式。

  • 應用程式關閉時。

您可以藉由處理事件來偵測應用程式何時變成非使用中 Application.Deactivated 狀態。

下列程式代碼示範如何處理 ActivatedDeactivated 事件,以判斷應用程式是否作用中。

<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也可以啟動與停用 。 如需詳細資訊,請參閱 Window.ActivatedWindow.Deactivated

注意

Application.Activated XBAP 也不會引發 或 Application.Deactivated

應用程式關閉

應用程式一旦關閉,其存留期間便告結束,而應用程式關閉的可能原因包括:

  • 使用者關閉每個 Window

  • 使用者關閉主要 Window

  • 用戶藉由註銷或關閉來結束 Windows 工作階段。

  • 已符合應用程式特定條件。

為了協助您管理應用程式關機, Application 請提供 Shutdown 方法、 ShutdownMode 屬性和 和 SessionEndingExit 事件。

注意

Shutdown 只能從具有 UIPermission的應用程式呼叫。 獨立 WPF 應用程式一律具有此許可權。 不過,在因特網區域部分信任安全性沙盒中執行的 XBAP 不會。

程式關閉模式

大多數應用程式會在所有視窗關閉或主視窗關閉時一併關閉。 不過有時候,應用程式關閉的時機可能是由其他應用程式特定條件決定。 您可以使用下列ShutdownMode其中一個列舉值進行設定ShutdownMode,以指定應用程式將關閉的條件:

的預設值 ShutdownModeOnLastWindowClose,這表示當使用者關閉應用程式的最後一個視窗時,應用程式會自動關閉。 不過,如果您的應用程式在主視窗關閉時應該關閉,則如果您設定 ShutdownModeOnMainWindowClose,WPF 就會自動關閉。 下列範例會顯示這一點。

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

當您有應用程式特定的關機條件時,您會設定 ShutdownModeOnExplicitShutdown。 在此情況下,您有責任藉由明確呼叫 Shutdown 方法關閉應用程式;否則,即使所有視窗都已關閉,您的應用程式仍會繼續執行。 請注意,Shutdown當為 OnLastWindowCloseOnMainWindowCloseShutdownMode,會以隱含方式呼叫 。

注意

ShutdownMode 可以從 XBAP 設定,但會被忽略;當 XBAP 在瀏覽器中巡覽或裝載 XBAP 的瀏覽器關閉時,一律會關閉 XBAP。 如需詳細資訊,請參閱 巡覽概觀

工作階段結束

屬性所描述的 ShutdownMode 關機條件是應用程式特有的。 不過在某些情況下,應用程式可能會因為外部狀況而關閉。 當使用者以下列動作結束 Windows 工作階段時,會發生最常見的外部條件:

  • 登出

  • 關機

  • 重新啟動

  • 休眠

若要偵測 Windows 會話何時結束,您可以處理 SessionEnding 事件,如下列範例所示。

<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

在此範例中,程式代碼會 ReasonSessionEnding 檢查 屬性,以判斷 Windows 會話的結束方式。 接著,它會使用這個值對使用者顯示確認訊息。 如果使用者不希望會話結束,程式代碼會將 設定 Canceltrue 以防止 Windows 會話結束。

注意

SessionEnding 不會針對 XBAP 引發。

結束

當應用程式關閉時,可能需要執行一些最終處理作業,例如保存應用程式狀態。 在這些情況下,您可以處理 Exit 事件,如同 App_Exit 事件處理程式在下列範例中所做的一樣。 它會定義為App.xaml檔案中的事件處理程式。 其實作會在App.xaml.csApplication.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

如需完整範例,請參閱跨應用程式工作階段保存和還原應用程式範圍的屬性

Exit 可以由獨立應用程式和 XBAP 處理。 針對 XBAP, Exit 會在下列情況下引發:

  • XBAP 會離開。

  • 在 Internet Explorer 中,裝載 XBAP 的索引標籤關閉時。

  • 關閉瀏覽器時。

結束碼

應用程式大部分是由作業系統啟動,以回應使用者要求。 不過,應用程式可由另一個應用程式啟動,以執行某項特定工作。 關閉已啟動的應用程式時,正在啟動的應用程式可能需要知道已啟動之應用程式的關閉條件。 在這些情況下,Windows 可讓應用程式在關機時傳回應用程式結束代碼。 根據預設,WPF 應用程式會傳回結束代碼值 0。

注意

當您從 Visual Studio 進行偵錯時,應用程式結束代碼會顯示在 應用程式關閉時的 [輸出 ] 視窗中,如下列訊息所示:

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

您可以按下 [檢視] 選單上的 [輸出] 來開啟 [輸出] 視窗。

若要變更結束代碼,您可以呼叫 Shutdown(Int32) 多載,以接受整數自變數做為結束代碼:

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

您可以藉由處理 Exit 事件來偵測結束代碼的值,並加以變更。 Exit事件處理程式會傳遞 ,ExitEventArgs其會使用 屬性來存取結束代碼ApplicationExitCode。 如需詳細資訊,請參閱Exit

注意

您可以在獨立應用程式和 XBAP 中設定結束代碼。 不過,XBAP 會忽略結束代碼值。

未處理的例外狀況

有時候,應用程式可能會在異常情況下關閉,例如擲回非預期的例外狀況時。 在此情況下,應用程式可能沒有可偵測及處理例外狀況的程式碼。 這種類型的例外狀況是未處理的例外狀況;在應用程式關閉之前,會顯示與下圖所示類似的通知。

Screenshot that shows an unhandled exception notification.

從使用者體驗的觀點來看,應用程式最好能夠藉由執行下列部分或所有動作,來避免此預設行為:

  • 顯示方便使用的資訊。

  • 嘗試繼續執行應用程式。

  • 記錄 Windows 事件記錄檔中詳細的開發人員易記例外狀況資訊。

實作此支援取決於能夠偵測未處理的例外狀況,這是 DispatcherUnhandledException 引發事件的用途。

<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

DispatcherUnhandledException事件處理程式會傳遞參數DispatcherUnhandledExceptionEventArgs,其中包含未處理的例外狀況相關內容資訊,包括例外狀況本身 (DispatcherUnhandledExceptionEventArgs.Exception)。 您可以使用這項資訊來判斷如何處理例外狀況。

當您處理 DispatcherUnhandledException時,應該將 屬性設定 DispatcherUnhandledExceptionEventArgs.Handledtrue,否則 WPF 仍會將例外狀況視為未處理,並還原為稍早所述的預設行為。 如果引發未處理的例外狀況,而且 DispatcherUnhandledException 未處理事件,或處理事件並 Handled 設定為 false,應用程式會立即關閉。 此外,不會引發其他 Application 事件。 因此,如果您的應用程式有必須在應用程式關閉之前執行的程式碼,您必須處理 DispatcherUnhandledException

雖然應用程式可能因為未處理的例外狀況而關閉,但是應用程式通常是為了回應使用者的要求而關閉 (如下節所述)。

應用程式存留期事件

獨立應用程式和 XBAP 沒有完全相同的存留期。 下圖說明獨立應用程式存留期內的主要事件,並顯示這些事件的引發順序。

Standalone Application - Application Object Events

同樣地,下圖說明 XBAP 存留期內的重要事件,並顯示引發事件的順序。

XBAP - Application Object Events

另請參閱