ホスト アプリと同じプロセスで実行するようにアプリ サービスを変換する

AppServiceConnection を使うと、別のアプリケーションがバック グラウンドでアプリをスリープ解除し、直接通信することができます。

インプロセスのアプリ サービスを導入することで、実行中の 2 つのフォアグラウンド アプリケーションはアプリ サービス接続経由で直接通信することができます。 アプリ サービスをフォアグラウンド アプリケーションとして同じプロセスで実行できるようになったため、アプリ間の通信がかなり簡単になっただけでなく、サービス コードを別個のプロジェクトに分離する必要がなくなりました。

アウトプロセス モデルのアプリ サービスをインプロセス モデルに変換するには、2 つの変更が必要です。 1 つ目は、マニフェストの変更です。

<Package
   ...
  <Applications>
      <Application Id=...
          ...
          EntryPoint="...">
          <Extensions>
              <uap:Extension Category="windows.appService">
                  <uap:AppService Name="InProcessAppService" />
              </uap:Extension>
          </Extensions>
          ...
      </Application>
  </Applications>

EntryPoint 属性を <Extension> 要素から削除します。アプリ サービスを呼び出したときに使われるエントリ ポイントが OnBackgroundActivated() になったためです。

2 つ目の変更として、サービス ロジックを別個のバックグラウンド タスク プロジェクトから、OnBackgroundActivated() によって呼び出すことができるメソッドに移動します。

これで、アプリケーションがアプリ サービスを直接実行できるようになります。 たとえば、App.xaml.cs では次のようになります。

[注] 下のコードは、例 1 (アウトプロセス サービス) で提供されているものとは異なります。 下のコードは単に説明のために用意されているものです。例 2 (インプロセス サービス) の一部として使用しないでください。 この記事で例 1 (アウトプロセス サービス) から例 2 (インプロセス サービス) への移行を続けるために、下のコード例ではなく、例 1 で提供されているコードを引き続き使用します。

using Windows.ApplicationModel.AppService;
using Windows.ApplicationModel.Background;
...

sealed partial class App : Application
{
  private AppServiceConnection _appServiceConnection;
  private BackgroundTaskDeferral _appServiceDeferral;

  ...

  protected override void OnBackgroundActivated(BackgroundActivatedEventArgs args)
  {
      base.OnBackgroundActivated(args);
      IBackgroundTaskInstance taskInstance = args.TaskInstance;
      AppServiceTriggerDetails appService = taskInstance.TriggerDetails as AppServiceTriggerDetails;
      _appServiceDeferral = taskInstance.GetDeferral();
      taskInstance.Canceled += OnAppServicesCanceled;
      _appServiceConnection = appService.AppServiceConnection;
      _appServiceConnection.RequestReceived += OnAppServiceRequestReceived;
      _appServiceConnection.ServiceClosed += AppServiceConnection_ServiceClosed;
  }

  private async void OnAppServiceRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
  {
      AppServiceDeferral messageDeferral = args.GetDeferral();
      ValueSet message = args.Request.Message;
      string text = message["Request"] as string;

      if ("Value" == text)
      {
          ValueSet returnMessage = new ValueSet();
          returnMessage.Add("Response", "True");
          await args.Request.SendResponseAsync(returnMessage);
      }
      messageDeferral.Complete();
  }

  private void OnAppServicesCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
  {
      _appServiceDeferral.Complete();
  }

  private void AppServiceConnection_ServiceClosed(AppServiceConnection sender, AppServiceClosedEventArgs args)
  {
      _appServiceDeferral.Complete();
  }
}

上記のコードでは、OnBackgroundActivated メソッドがアプリ サービスのアクティブ化を処理します。 AppServiceConnection を通じた通信に必要なすべてのイベントが登録され、タスク保留オブジェクトが格納されて、アプリケーション間の通信が完了したときに完了とマークできるようになります。

アプリが要求を読み取り、Key 文字列と Value 文字列が存在するかどうかを確認する ValueSet を読み取ります。 存在する場合、App Service は、AppServiceConnectionResponseもう一方の側のアプリに対して、 と True 文字列の値のペアを返します。

他のアプリとの接続と通信について詳しくは、「アプリ サービスの作成と利用」をご覧ください。