SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

UWPアプリ開発の最前線

UWPアプリの自動起動/再起動/事前起動/コマンドラインから起動/終了キャンセル
~コードからアプリの起動と終了を制御する

UWPアプリ開発の最前線 第12回


  • X ポスト
  • このエントリーをはてなブックマークに追加

UWPアプリが閉じられるのをキャンセルする

終了確認ダイアログを出しているサンプルアプリ
終了確認ダイアログを出しているサンプルアプリ
  • アプリを終了する操作をキャンセルできます
  • サイドローディングで配布する業務アプリを想定した機能で、ストアでの公開は制限されます
  • Windows 10 version 1703(build 15063)から利用可能

 アプリが閉じられようとするときのイベントハンドラーが使えるようになりました。そのイベントハンドラーに渡された引数のHandledプロパティをtrueにセットすれば、閉じられるのをキャンセルできます。[×]ボタン/[Alt]+[F4]キー/タスクバーからの終了操作など、ユーザーがアプリを終了しようとする操作をキャンセルできます。

 この機能はサイドローディングで配布する業務アプリなどを想定しているようで、Microsoftストアでは制限されます。ストアでは、ファイルの「フルアクセス機能」と同様の扱いになります。

マニフェストの変更

 この機能を使うには、「制限付き機能」(restricted capabilities)であるconfirmAppCloseケイパビリティの宣言がマニフェストに必要です(capability=ある目的の達成に必要な能力)。

 ソリューションエクスプローラーでPackage.appxmanifestを右クリックし、[コードの表示]を選んで、マニフェストを直接編集します。

 まず、先頭のPackageタグに名前空間「rescap」を追加します(次のコード)。

マニフェストに名前空間を追加する(Package.appxmanifest
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
  xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
  xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
  xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
  IgnorableNamespaces="uap mp rescap">

 次に、Capabilities要素の中に、次のコードのようにrescap:Capability要素を追加します。Capabilities要素が見当たらないときは、</Package>閉じタグの上にCapabilities要素を追加してください。

マニフェストにconfirmAppCloseケイパビリティを追加する(Package.appxmanifest
  <Capabilities>
    <Capability Name="internetClient" />
    <rescap:Capability Name="confirmAppClose" />
  </Capabilities>
</Package>

 ここでrescapは"restricted capability"(制限されているケイパビリティ)の意味です。また、rescap:Capability要素を記述すると警告が出るかもしれませんが、無視してください。なお、rescap:Capability要素を記述すると、WACK(Windows App Cert. Kit)のテストには通らなくなります。

アプリが閉じられるのをキャンセルするコード

 以上のようにマニフェストを修正すると、SystemNavigationManagerPreviewクラス(Windows.UI.Core.Preview名前空間)のCloseRequestedイベントが使えるようになります。アプリが閉じられるのをキャンセルするには、そのイベントハンドラーの中で引数のHandledプロパティにtrueをセットします(次のコード)。

アプリが閉じられるのをキャンセルする
SystemNavigationManagerPreview.GetForCurrentView().CloseRequested += (s, e) =>
{
  // 閉じられるのをキャンセルする
  e.Handled = true;
};

 上のようにしただけではアプリをまったく終了できなくなってしまいますから、実際には次のコードのように、ダイアログを出してユーザーに決めてもらうようにします。awaitしてから(=いったん制御を返してしまってから)Handledプロパティを変更しても間に合わない(=アプリは閉じてしまう)ことには注意してください。つまり、ダイアログを出す前にHandledプロパティを変更しておく必要があります。ユーザーが終了することを選んだら、あらためてAppクラスのExitメソッドを呼び出してアプリを終了させます。

アプリを終了するかユーザーに尋ねる(App.xaml.CloseRequested.cs
SystemNavigationManagerPreview.GetForCurrentView().CloseRequested += async (s, e) =>
{
  // 閉じられるのをキャンセルする
  e.Handled = true;

  // ダイアログを表示する
  ContentDialog dialog = new ContentDialog
  {
    Title = "アプリを終了しますか?",
    Content = "[×] ボタンが押されましたが、アプリを終了してもよいですか",
    CloseButtonText = "キャンセル",
    PrimaryButtonText = "終了",
    DefaultButton = ContentDialogButton.Primary
  };
  ContentDialogResult result = await dialog.ShowAsync();
  if (result == ContentDialogResult.Primary)
  {
    // すでにキャンセルしてしまっているので、
    // 必要ならばあらためてアプリを終了させる。
    App.Current.Exit();
    // ↑Exitすると、OnSuspendingなどは実行されないので注意!
  }
};

 なお、Exitメソッドでの終了は「異常終了」です。OnSuspendingイベントなどは発生しませんので、アプリ中断時に行う処理はExitメソッドを呼び出す前に終わらせておいてください。また、終了時のウィンドウの位置やサイズも記憶されません(サンプルコードにはウィンドウサイズを復元するコードを入れてあります)。

次のページ
まとめ

関連リンク

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
UWPアプリ開発の最前線連載記事一覧

もっと読む

この記事の著者

biac(ばいあっく)

HONDA R&Dで自動車の設計をやっていた機械屋さんが、技術の進化スピードに魅かれてプログラマーに。以来30年ほど、より良いコードをどうやったら作れるか、模索の人生。わんくま同盟の勉強会(名古屋)で、よく喋ってたりする。2014/10~2019/6 Microsoft MVP (Windows Devel...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/11325 2019/07/22 18:45

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング