Windows アプリ SDK デスクトップ アプリのアプリ ライフサイクル

この記事では、起動から終了までのWindows アプリ SDK デスクトップ アプリのライフサイクルについて説明します。 ライフサイクルを理解すると、状態の管理、リソースの節約、スムーズなユーザー エクスペリエンスの実現に役立ちます。

Important

UWP アプリとは異なり、デスクトップ アプリ (WinUI 3 を含む) は 、バックグラウンドでの自動中断と終了の UWP プロセス ライフサイクル管理 (PLM) モデルの対象になりません。 ユーザーが閉じるか、プロセスが終了するまで、実行を続けます。 ただし、パッケージ化されたデスクトップ アプリは引き続きシステム全体の電源ポリシーとリソース ポリシーの対象となります。たとえば、Modern Standby はデバイスがスリープ状態になったときにすべてのユーザー モード プロセス (アプリを含む) を中断できます。また、Windowsは、バックグラウンド アプリまたは最小化されたアプリの CPU 優先度とサービス品質を調整するために効率モード (EcoQoS) を適用できます。 アプリでは、予期しないシャットダウン (電源損失、OS の更新、タスク マネージャーを使用してプロセスを終了するユーザーなど) を適切に処理する必要があり、バックグラウンドで常にフルスピードの CPU アクセスを持っているとは限りません。

ライフサイクルの概要

Windows アプリ SDK デスクトップ アプリのライフサイクルは、UWP よりも簡単です。

State Description
実行されていません アプリ プロセスが開始されていません。
実行中 アプリがアクティブです。 ウィンドウが表示される場合と表示されない場合があります。
閉鎖 ユーザー (またはシステム) がプロセスを終了しました。

中断状態がないため、UWP アプリと同様に Suspending イベントや Resuming イベントを処理する必要はありません。 代わりに、次の点に注目してください。

  • ウィンドウが閉じるか、アプリがシャットダウンしたときにユーザーの状態を保存する。
  • アクティブ化の処理 (起動、ファイル、プロトコル、またはその他のアクティブ化の種類)。
  • ポータブルデバイスのバッテリーを節約するためにバックグラウンド作業を効率的に管理します。

アプリの起動

ユーザーがアプリを起動すると、Microsoft。Ui。Xaml.Application.OnLaunched メソッドが実行されます。 これを使用してメイン ウィンドウを初期化し、最初のページに移動します。

public partial class App : Microsoft.UI.Xaml.Application
{
    private Microsoft.UI.Xaml.Window? m_window;

    protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
    {
        m_window = new MainWindow();
        m_window.Activate();
    }
}

// MainWindow is the window class generated by the WinUI 3 project
// template (MainWindow.xaml / MainWindow.xaml.cs).
public partial class MainWindow : Microsoft.UI.Xaml.Window
{
}

Note

Windows アプリ SDKデスクトップ アプリは、システムからPreviousExecutionState値を受け取りません。 クラッシュまたは予期しない終了後に状態を復元する必要がある場合は、独自の状態永続化メカニズムを実装します (たとえば、タイマーのローカル ファイルに状態を保存したり、重要なアクションが完了したときなど)。

アプリのアクティブ化

Windows アプリ SDK は、Microsoft.Windows.AppLifecycle 名前空間を通じて、豊富なアクティブ化サポートを提供します。 アプリは次の方法でアクティブ化できます。

  • 既定の起動 - ユーザーがアプリ アイコンを選択します。
  • ファイルのアクティブ化 - ユーザーがアプリに関連付けられているファイルの種類を開きます。
  • プロトコルのアクティブ化 — アプリに登録されている URI スキームが呼び出されます。
  • スタートアップのアクティブ化 - ユーザー ログオン時に開始するようにアプリが登録されます。
  • その他 — トースト通知、共有ターゲット、その他のアクティブ化の種類。

AppInstance.GetActivatedEventArgs を使用して、アクティブ化の種類を確認します。

using Microsoft.Windows.AppLifecycle;

var activatedArgs = AppInstance.GetCurrent().GetActivatedEventArgs();

switch (activatedArgs.Kind)
{
    case ExtendedActivationKind.File:
        var fileArgs = activatedArgs.Data as
            Windows.ApplicationModel.Activation.IFileActivatedEventArgs;
        // Handle the file
        break;

    case ExtendedActivationKind.Protocol:
        var protocolArgs = activatedArgs.Data as
            Windows.ApplicationModel.Activation.IProtocolActivatedEventArgs;
        // Handle the URI
        break;

    case ExtendedActivationKind.Launch:
    default:
        // Standard launch
        break;
}

パッケージ アプリは、 Package.appxmanifestを介してファイルとプロトコルのアクティブ化に登録します。 パッケージ化されていないアプリにはマニフェストがないため、 Microsoft.Windows.AppLifecycle.ActivationRegistrationManagerを使用してコードに同じアクティブ化の種類を登録します。 両方の方法の詳細なチュートリアルについては、「Windows アプリ SDKのアプリのアクティブ化」を参照してください。

バックグラウンドとフォアグラウンドでの実行

デスクトップ アプリは、フォアグラウンドに存在するかどうかに関係なく、引き続き実行されます。 ユーザーが別のアプリに切り替えたときに、システムがスレッドを停止したり、メモリを再利用したりすることはありません。 ただし、リソースの使用状況を最適化するために、可視性の変更に対応することはできます。

  • ウィンドウが最小化されている場合は、高価な GPU またはレンダリング リソースを解放します。
  • ウィンドウがフォーカスを失ったときにアニメーションまたはメディア プレビューを一時停止します。
  • バックグラウンドでのポーリングのタイマーの頻度を減らします。

Microsoft.UI.Xaml.WindowVisibilityChanged イベントを公開していません。 代わりに、 Window.Activated イベントを使用して、ウィンドウがフォーカスを取得または失うタイミングを検出するか、 AppWindow.Changed を使用して発表者の状態 (最小化や復元など) への変更を検出します。

// m_window is the field declared on your App type (see "App launch" above).
Microsoft.UI.Xaml.Window m_window = this;

m_window.Activated += (sender, args) =>
{
    if (args.WindowActivationState == WindowActivationState.Deactivated)
    {
        // Window lost focus — consider reducing work,
        // for example pausing animations or media preview
    }
    else
    {
        // Window is active — resume normal work
    }
};

// To specifically detect minimize/restore, use AppWindow.Changed
var appWindow = m_window.AppWindow;
appWindow.Changed += (sender, args) =>
{
    if (args.DidPresenterChange)
    {
        if (sender.Presenter is OverlappedPresenter presenter &&
            presenter.State == OverlappedPresenterState.Minimized)
        {
            // Window is minimized — pause expensive rendering
        }
        else
        {
            // Window is restored — resume rendering
        }
    }
};

Tip

バッテリ駆動デバイスでは、アプリが表示されない場合にバックグラウンド作業を減らすと、システムが中断を強制しない場合でも、バッテリの寿命とシステムの応答性が向上します。

状態の保存

デスクトップ アプリは中断されないため、状態を保存するタイミングを制御します。 推奨される方法:

  • ウィンドウが閉じた場合 - データを保持するために Window.Closed イベントを処理します。
  • 定期的な保存 — タイマーを使用して、間隔 (60 秒ごとなど) で状態を保存します。
  • 重要なアクションの場合 - ユーザーが重要なアクションを完了した後に保存します (編集の完了など)。
// m_window is the field declared on your App type (see "App launch" above).
Microsoft.UI.Xaml.Window m_window = this;

m_window.Closed += (sender, args) =>
{
    SaveApplicationState();
};

// Replace with your own logic to persist app state.
void SaveApplicationState() { }

アプリのクローズと終了処理

デスクトップ アプリは、次の場合に終了します。

  • ユーザーは最後のウィンドウを閉じます。
  • コードは Application.Current.Exit()を呼び出します。
  • プロセスは外部で終了します (タスク マネージャー、システムのシャットダウン)。

UWP のように、"リソースを解放するためにシステムによって終了される" 状態はありません。 アプリは、明示的に終了するまで実行されます。

Note

アプリがクラッシュすると、最初から再起動します。 データ損失を最小限に抑えるために、定期的な状態の保存を実装します。

UWP アプリのライフサイクルとの違い

Behavior UWP Windows アプリ SDK (デスクトップ)
自動停止 (PLM) はい — バックグラウンドにしてから数秒後 いいえ — ただし、デバイス全体が最新のスタンバイ状態に入る可能性があります
メモリを解放するためのシステム終了 はい - 中断されたアプリが終了する可能性があります いいえ
Suspending / Resuming イベント はい 適用なし
事前起動 はい (オプトイン) いいえ
バックグラウンド状態を強制 はい いいえ — ただし、効率モード (EcoQoS) はバックグラウンドアプリを調整する可能性があります
終了後の状態の復元 適切な UX に必要 省略可能 — 独自の実装