アプリ サービスの作成と利用Create and consume an app service

アプリ サービスは、他の UWP アプリにサービスを提供する UWP アプリです。App services are UWP apps that provide services to other UWP apps. これは、デバイス上にある Web サービスのようなものです。They are analogous to web services, on a device. アプリ サービスは、バック グラウンド タスクとしてホスト アプリで実行され、そのサービスを他のアプリに提供することができます。An app service runs as a background task in the host app and can provide its service to other apps. たとえば、アプリ サービスによって、他のアプリで使用できるバー コード スキャナー サービスが提供される場合があります。For example, an app service might provide a bar code scanner service that other apps could use. また、アプリのエンタープライズ スイートに共通のスペル チェック アプリ サービスを備えておき、そのサービスを同じスイート内の他のアプリから利用可能にする場合もあるでしょう。Or perhaps an Enterprise suite of apps has a common spell checking app service that is available to the other apps in the suite. アプリ サービスでは、同じデバイス上のアプリから呼び出せる UI を持たないサービスを作成できます。また、Windows 10 バージョン 1607 以降では、リモート デバイスからも呼び出せます。App services let you create UI-less services that apps can call on the same device, and starting with Windows 10, version 1607, on remote devices.

Windows 10 バージョン 1607 以降では、ホスト アプリと同じプロセスで実行されるアプリ サービスを作成できます。Starting in Windows 10, version 1607, you can create app services that run in the same process as the host app. この記事では、別のバックグラウンド プロセスで実行されるアプリ サービスの作成と利用に重点を置いて説明します。This article focuses on creating and consuming an app service that runs in a separate background process. プロバイダーと同じプロセスでアプリ サービスを実行する詳細については、「ホスト アプリと同じプロセスで実行するようにアプリ サービスを変換する」をご覧ください。See Convert an app service to run in the same process as its host app for more details about running an app service in the same process as the provider.

アプリ サービスのコード サンプルについては、「ユニバーサル Windows プラットフォーム (UWP) アプリのサンプル」を参照してください。For an app service code sample, see Universal Windows Platform (UWP) app samples.

新しいアプリ サービス プロバイダー プロジェクトの作成Create a new app service provider project

このトピックでは、わかりやすくするためにすべてを 1 つのソリューションで作成します。In this how-to, we'll create everything in one solution for simplicity.

  • Microsoft Visual Studio で、新しい UWP アプリ プロジェクトを作成し、これに AppServiceProvider という名前を付けます。In Microsoft Visual Studio, create a new UWP app project and name it AppServiceProvider. ([新しいプロジェクト] ダイアログ ボックスで、[テンプレート] > [他の言語] > [Visual C#] > [Windows] > [Windows ユニバーサル] > [空白のアプリ (Windows ユニバーサル)] の順にクリックします)。(In the New Project dialog box, select Templates > Other Languages > Visual C# > Windows > Windows Universal > Blank app (Windows Universal)). これは、他の UWP アプリがアプリ サービスを利用できるアプリとなります。This will be the app that makes the app service available to other UWP apps.
  • プロジェクトのターゲット バージョンの選択を求められたら、10.0.14393 以上を選びます。When asked to select a Target Version for the project, select at least 10.0.14393. 新しい SupportsMultipleInstances 属性を使用する場合には、Visual Studio 2017 を使用して、10.0.15063 (Windows 10 Creators Update) 以降をターゲットとする必要があります。If you want to use the new SupportsMultipleInstances attribute, you must be using Visual Studio 2017 and target 10.0.15063 (Windows 10 Creators Update) or higher.

package.appxmanifest へのアプリ サービスの拡張機能の追加Add an app service extension to package.appxmanifest

AppServiceProvider プロジェクトの Package.appxmanifest ファイルで、次の AppService 拡張機能を <Application> 要素内に追加します。In the AppServiceProvider project's Package.appxmanifest file, add the following AppService extension inside the <Application> element. この例では、com.Microsoft.Inventory サービスをアドバタイズし、このアプリをアプリ サービス プロバイダーとして識別します。This example advertises the com.Microsoft.Inventory service and is what identifies this app as an app service provider. 実際のサービスは、バックグラウンド タスクとして実装されます。The actual service will be implemented as a background task. アプリ サービスのプロジェクトは、サービスを他のアプリに公開します。The app service project exposes the service to other apps. サービス名には逆のドメイン名スタイルを使うことをお勧めします。We recommend using a reverse domain name style for the service name.

xmlns:uap4 名前空間のプレフィックスと uap4:SupportsMultipleInstances 属性は、Windows SDK バージョン 10.0.15063 以降をターゲットとしている場合のみ有効です。Note that the xmlns:uap4 namespace prefix and the uap4:SupportsMultipleInstances attribute are only valid if you are targeting Windows SDK version 10.0.15063 or higher. 以前のバージョンの SDK をターゲットとしている場合には、それらは安全に削除できます。You can safely remove them if you are targeting older SDK versions.

<Package
    ...
    xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
    xmlns:uap4="http://schemas.microsoft.com/appx/manifest/uap/windows10/4"
    ...
    <Applications>
        <Application Id="AppServicesProvider.App"
          Executable="$targetnametoken$.exe"
          EntryPoint="AppServicesProvider.App">
          ...
          <Extensions>
            <uap:Extension Category="windows.appService" EntryPoint="MyAppService.Inventory">
              <uap3:AppService Name="com.microsoft.inventory" uap4:SupportsMultipleInstances="true"/>
            </uap:Extension>
          </Extensions>
          ...
        </Application>
    </Applications>

Category 属性は、このアプリケーションをアプリ サービス プロバイダーとして識別します。The Category attribute identifies this application as an app service provider.

EntryPoint 属性は、サービスを実装する名前空間修飾クラスを識別します。これについては、次に実装します。The EntryPoint attribute identifies the namespace qualified class that implements the service, which we'll implement next.

SupportsMultipleInstances 属性は、アプリ サービスが呼び出されるたびに、新しいプロセスで実行する必要があることを示します。The SupportsMultipleInstances attribute indicates that each time the app service is called that it should run in a new process. これは必須ではありませんが、その機能を必要とし、10.0.15063 SDK (Windows 10 Creators Update) 以降をターゲットとしている場合には、利用できます。This is not required but is available to you if you need that functionality and are targeting the 10.0.15063 SDK (Windows 10 Creators Update) or higher. また、先頭に uap4 名前空間を付ける必要があります。It also should be prefaced by the uap4 namespace.

アプリ サービスの作成Create the app service

  1. アプリ サービスは、バックグラウンド タスクとして実装できます。An app service can be implemented as a background task. これにより、フォアグラウンド アプリケーションは、別のアプリケーションのアプリ サービスを呼び出すことができます。This enables a foreground application to invoke an app service in another application. アプリ サービスをバックグラウンド タスクとして作成するには、MyAppService という名前の新しい Windows ランタイム コンポーネント プロジェクトをソリューションに追加 ([ファイル] > [追加] > [新しいプロジェクト]) します。To create an app service as a background task, add a new Windows Runtime Component project to the solution (File > Add > New Project) named MyAppService. ([新しいプロジェクトの追加] ダイアログ ボックスで、[インストール済み] > [他の言語] > [Visual C#] > [Windows] > [Windows ユニバーサル] > [Windows ランタイム コンポーネント (Windows ユニバーサル)] の順に選びます。)(In the Add New Project dialog box, choose Installed > Other Languages > Visual C# > Windows > Windows Universal > Windows Runtime Component (Windows Universal)
  2. AppServiceProviderプロジェクトで、新しい MyAppServiceプロジェクト (ソリューション エクスプ ローラーで、[AppServiceProvider] を右クリックし、[プロジェクト] > [追加] > [リファレンス] > [プロジェクト] > [ソリューション] から [MyAppService] > [OK] をクリック) へのプロジェクト間の参照を追加します。In the AppServiceProvider project, add a project-to-project reference to the new MyAppService project (In the Solution Explorer, right-click on the AppServiceProvider project > Add > Reference > Projects > Solution, select MyAppService > OK). 参照を追加しない場合でも、アプリ サービスは実行時に接続されないため、この手順は重要です。This step is critical because if you do not add the reference, the app service won't connect at runtime.
  3. MyappService プロジェクトで、Class1.cs の上部に、次の using ステートメントを追加します。In the MyappService project, add the following using statements to the top of Class1.cs:

    using Windows.ApplicationModel.AppService;
    using Windows.ApplicationModel.Background;
    using Windows.Foundation.Collections;
    
  4. Class1 のスタブ コードを、Inventory という名前の新しいバックグラウンド タスク クラスに置き換えます。Replace the stub code for Class1 with a new background task class named Inventory:

    public sealed class Inventory : IBackgroundTask
    {
        private BackgroundTaskDeferral backgroundTaskDeferral;
        private AppServiceConnection appServiceconnection;
        private String[] inventoryItems = new string[] { "Robot vacuum", "Chair" };
        private double[] inventoryPrices = new double[] { 129.99, 88.99 };
    
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            this.backgroundTaskDeferral = taskInstance.GetDeferral(); // Get a deferral so that the service isn't terminated.
            taskInstance.Canceled += OnTaskCanceled; // Associate a cancellation handler with the background task.
    
            // Retrieve the app service connection and set up a listener for incoming app service requests.
            var details = taskInstance.TriggerDetails as AppServiceTriggerDetails;
            appServiceconnection = details.AppServiceConnection;
            appServiceconnection.RequestReceived += OnRequestReceived;
        }
    
        private async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
        {
            // This function is called when the app service receives a request
        }
    
        private void OnTaskCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
        {
            if (this.backgroundTaskDeferral != null)
            {
                // Complete the service deferral.
                this.backgroundTaskDeferral.Complete();
            }
        }
    }
    

    このクラスは、アプリ サービスが作業を実行する場所です。This class is where the app service will do its work.

    バックグラウンド タスクが作成されると、Run() が呼び出されます。Run() is called when the background task is created. バックグラウンド タスクは Run が完了すると終了するため、バックグラウンド タスクが要求に引き続き対応できるように、コードは保留されます。Because background tasks are terminated after Run completes, the code takes out a deferral so that the background task will stay up to serve requests. バックグラウンド タスクとして実装されたアプリ サービスは、呼び出しを受け取った後、約 30 秒間に再度呼び出されない限り、または保留されない限り、約 30 秒間有効になっています。アプリ サービスが同じプロセスで呼び出し元として実装されると、アプリ サービスの有効期間は呼び出し元の有効期間に関連付けられます。An app service that is implemented as a background task will stay alive for about 30 seconds after it receives a call unless it is called again within that time window or a deferral is taken out. If the app service is implemented in the same process as the caller, the lifetime of the app service is tied to the lifetime of the caller.

    アプリ サービスの有効期間は、呼び出し元に依存します。The lifetime of the app service depends on the caller:

    1. 呼び出し元がフォアグラウンドである場合は、アプリ サービスの有効期間は、呼び出し元と同じです。If the caller is in foreground, the app service lifetime is the same as the caller.
    2. 呼び出し元がバックグラウンドである場合は、アプリ サービスの有効期間は 30 秒です。If the caller is in background, the app service gets 30 seconds to run. 保留されると、1 回 5 秒追加されます。Taking out a deferral provides an additional one time 5 seconds.

    タスクが取り消されると、OnTaskCanceled() が呼び出されます。OnTaskCanceled() is called when the task is canceled. タスクが取り消されるのは、クライアント アプリが AppServiceConnection を破棄したとき、クライアント アプリが中断されたとき、OS がシャットダウンまたはスリープ状態になったとき、または OS がリソース不足になりタスクを実行できなくなったときです。The task is cancelled when the client app disposes the AppServiceConnection, the client app is suspended, the OS is shut down or sleeps, or the OS runs out of resources to run the task.

アプリ サービスのコードを記述するWrite the code for the app service

OnRequestReceived() は、アプリ サービスのコードが配置される場所です。OnRequestReceived() is where the code for the app service goes. MyAppService の Class1.cs のスタブ OnRequestReceived() を、次の例のコードに置き換えます。Replace the stub OnRequestReceived() in MyAppService's Class1.cs with the code from this example. このコードは、インベントリの項目のインデックスを取得し、コマンド文字列と共にサービスに渡して、指定したインベントリ項目の名前と価格を取得します。This code gets an index for an inventory item and passes it, along with a command string, to the service to retrieve the name and the price of the specified inventory item. 独自のプロジェクトには、エラー処理コードを追加します。For your own projects, add error handling code.

private async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
{
    // Get a deferral because we use an awaitable API below to respond to the message
    // and we don't want this call to get cancelled while we are waiting.
    var messageDeferral = args.GetDeferral();

    ValueSet message = args.Request.Message;
    ValueSet returnData = new ValueSet();

    string command = message["Command"] as string;
    int? inventoryIndex = message["ID"] as int?;

    if ( inventoryIndex.HasValue &&
         inventoryIndex.Value >= 0 &&
         inventoryIndex.Value < inventoryItems.GetLength(0))
    {
        switch (command)
        {
            case "Price":
            {
                returnData.Add("Result", inventoryPrices[inventoryIndex.Value]);
                returnData.Add("Status", "OK");
                break;
            }

            case "Item":
            {
                returnData.Add("Result", inventoryItems[inventoryIndex.Value]);
                returnData.Add("Status", "OK");
                break;
            }

            default:
            {
                returnData.Add("Status", "Fail: unknown command");
                break;
            }
        }
    }
    else
    {
        returnData.Add("Status", "Fail: Index out of range");
    }

    try
    {
        await args.Request.SendResponseAsync(returnData); // Return the data to the caller.
    }
    catch (Exception e)
    {
        // your exception handling code here
    }
    finally
    {
        // Complete the deferral so that the platform knows that we're done responding to the app service call.
        // Note for error handling: this must be called even if SendResponseAsync() throws an exception.
        messageDeferral.Complete();
    }
}

OnRequestReceived()async であることに注意してください。この例では、SendResponseAsync への待機可能なメソッド呼び出しを行うためです。Note that OnRequestReceived() is async because we make an awaitable method call to SendResponseAsync in this example.

保留が行われるのは、サービスが OnRequestReceived ハンドラーで async メソッドを使用できるようにするためです。A deferral is taken so that the service can use async methods in the OnRequestReceived handler. これにより、OnRequestReceived への呼び出しは、メッセージの処理が完了するまで完了しません。It ensures that the call to OnRequestReceived does not complete until it is done processing the message. SendResponseAsync が結果を呼び出し元に送ります。SendResponseAsync sends the result to the caller. SendResponseAsync は、呼び出しの完了時に通知しません。SendResponseAsync does not signal the completion of the call. OnRequestReceived が完了したことを SendMessageAsync に通知するのは、保留の完了時です。It is the completion of the deferral that signals to SendMessageAsync that OnRequestReceived has completed. SendResponseAsync() の呼び出しは、SendResponseAsync() が例外をスローした場合でも保留を完了する必要があるため、try/finally ブロックでラップされます。The call to SendResponseAsync() is wrapped in a try/finally block because you must complete the deferral even if SendResponseAsync() throws an exception.

アプリ サービスは ValueSet を使って情報を交換します。App services use a ValueSet to exchange information. 渡すことができるデータのサイズは、システム リソースによってのみ制限されます。The size of the data you may pass is only limited by system resources. ValueSet で使うことができる定義済みのキーはありません。There are no predefined keys for you to use in your ValueSet. アプリ サービスのプロトコルの定義に使うキーの値を決定する必要があります。You must determine which key values you will use to define the protocol for your app service. 呼び出し元は、そのプロトコルを念頭に置いて記述する必要があります。The caller must be written with that protocol in mind. この例では、アプリ サービスがインベントリ項目またはその価格の名前を提供するかどうかを示す値を持つ、Command という名前のキーを選びました。In this example, we have chosen a key named Command that has a value that indicates whether we want the app service to provide the name of the inventory item or its price. インベントリ名のインデックスは、ID キーに保存されています。The index of the inventory name is stored under the ID key. 戻り値は Result キーに保存されます。The return value is stored under the Result key.

AppServiceClosedStatus 列挙体が呼び出し元に返され、アプリ サービスの呼び出した成功したか失敗したかを示します。An AppServiceClosedStatus enum is returned to the caller to indicate whether the call to the app service succeeded or failed. アプリ サービスへの呼び出しが失敗する例として、OS がサービスのエンドポイントを中止した、リソースが超過したなどがあります。An example of how the call to the app service could fail is if the OS aborts the service endpoint because its resources have been exceeded. ValueSet を通じて、さらにエラー情報を取得することができます。You can return additional error information via the ValueSet. この例では、Status という名前のキーを使って、より詳細なエラー情報を呼び出し元に返します。In this example, we use a key named Status to return more detailed error information to the caller.

SendResponseAsync の呼び出しからは、ValueSet が呼び出し元に返されます。The call to SendResponseAsync returns the ValueSet to the caller.

サービス アプリを展開して、パッケージ ファミリ名を取得するDeploy the service app and get the package family name

クライアントから呼び出す前に、アプリ サービス プロバイダーのアプリを展開する必要があります。The app service provider app must be deployed before you can call it from a client. これを呼び出すには、アプリ サービスのアプリのパッケージ ファミリ名も必要になります。You will also need the package family name of the app service app in order to call it.

アプリ サービスのアプリのパッケージ ファミリ名を取得する 1 つの方法は、AppServiceProvider プロジェクト内から (たとえば、App.xaml.cs の public App() から) Windows.ApplicationModel.Package.Current.Id.FamilyName を呼び出し、結果をメモします。One way to get the package family name of the app service application is to call Windows.ApplicationModel.Package.Current.Id.FamilyName from within the AppServiceProvider project (for example, from public App() in App.xaml.cs) and note the result. Microsoft Visual Studio で AppServiceProvider を実行するには、ソリューション エクスプローラー ウィンドウで、スタートアップ プロジェクトとして設定し、プロジェクトを実行します。To run AppServiceProvider in Microsoft Visual Studio, set it as the startup project in the Solution Explorer window and run the project.

パッケージ ファミリ名を取得する別の方法として、ソリューションを配置し ([ビルド] > [ソリューションの配置])、出力ウィンドウで完全なパッケージ名をメモします ([表示] > [出力])。Another way to get the package family name is to deploy the solution (Build > Deploy solution) and note the full package name in the output window (View > Output). パッケージ名を派生するには、出力ウィンドウの文字列からプラットフォーム情報を削除する必要があります。You must remove the platform information from the string in the output window to derive the package name. たとえば、完全なパッケージ名が出力ウィンドウで Microsoft.SDKSamples.AppServicesProvider.CPP_1.0.0.0_x86__8wekyb3d8bbwe と報告された場合、Microsoft.SDKSamples.AppServicesProvider.CPP_8wekyb3d8bbwe" を削除し、"1.0.0.0_x86__"(1.0.0.0\_x86\_\_" leaving "Microsoft.SDKSamples.AppServicesProvider.CPP_8wekyb3d8bbwe) がパッケージ ファミリ名となります。For example, if the full package name reported in the output window was Microsoft.SDKSamples.AppServicesProvider.CPP_1.0.0.0_x86__8wekyb3d8bbwe, you would extract 1.0.0.0\_x86\_\_" leaving "Microsoft.SDKSamples.AppServicesProvider.CPP_8wekyb3d8bbwe as the package family name.

アプリ サービスを呼び出すクライアントを作成するWrite a client to call the app service

  1. [ファイル] > [追加] > [新しいプロジェクト] で、新しい空の Windows ユニバーサル アプリ プロジェクトをソリューションに追加します。Add a new blank Windows Universal app project to the solution with File > Add > New Project. [新しいプロジェクトの追加] ダイアログ ボックスで、[インストール済み] > [他の言語] > [Visual C#] > [Windows] > [Windows ユニバーサル] > [空のアプリ (Windows ユニバーサル)] ** の順に選び、[ClientApp]** と名前を付けます。In the Add New Project dialog box, choose Installed > Other languages > Visual C# > Windows > Windows Universal > Blank App (Windows Universal) and name it ClientApp.
  2. ClientApp プロジェクトで、MainPage.xaml.cs の上部に、次の using ステートメントを追加します。In the ClientApp project, add the following using statement to the top of MainPage.xaml.cs: cs >using Windows.ApplicationModel.AppService;
  3. テキスト ボックスとボタンを MainPage.xaml に追加します。Add a text box and a button to MainPage.xaml.
  4. ボタンのクリック ハンドラーを追加し、ボタン ハンドラーの署名にキーワード async を追加します。Add a button click handler for the button and add the keyword async to the button handler's signature.
  5. ボタンのクリック ハンドラーのスタブを、次のコードで置き換えます。Replace the stub of your button click handler with the following code. 必ず、inventoryService フィールドの宣言を含めます。Be sure to include the inventoryService field declaration.

    private AppServiceConnection inventoryService;
    private async void button_Click(object sender, RoutedEventArgs e)
    {
       // Add the connection.
       if (this.inventoryService == null)
       {
           this.inventoryService = new AppServiceConnection();
    
           // Here, we use the app service name defined in the app service provider's Package.appxmanifest file in the <Extension> section.
           this.inventoryService.AppServiceName = "com.microsoft.inventory";
    
           // Use Windows.ApplicationModel.Package.Current.Id.FamilyName within the app service provider to get this value.
           this.inventoryService.PackageFamilyName = "replace with the package family name";
    
           var status = await this.inventoryService.OpenAsync();
           if (status != AppServiceConnectionStatus.Success)
           {
               textBox.Text= "Failed to connect";
               return;
           }
       }
    
       // Call the service.
       int idx = int.Parse(textBox.Text);
       var message = new ValueSet();
       message.Add("Command", "Item");
       message.Add("ID", idx);
       AppServiceResponse response = await this.inventoryService.SendMessageAsync(message);
       string result = "";
    
       if (response.Status == AppServiceResponseStatus.Success)
       {
           // Get the data  that the service sent  to us.
           if (response.Message["Status"] as string == "OK")
           {
               result = response.Message["Result"] as string;
           }
       }
    
       message.Clear();
       message.Add("Command", "Price");
       message.Add("ID", idx);
       response = await this.inventoryService.SendMessageAsync(message);
    
       if (response.Status == AppServiceResponseStatus.Success)
       {
           // Get the data that the service sent to us.
           if (response.Message["Status"] as string == "OK")
           {
               result += " : Price = " + response.Message["Result"] as string;
           }
       }
    
       textBox.Text = result;
    }
    

    this.inventoryService.PackageFamilyName = "replace with the package family name"; のパッケージ ファミリ名を、「サービス アプリを展開して、パッケージ ファミリ名を取得する」で得た AppServiceProvider プロジェクトのパッケージ ファミリ名に置き換えます。Replace the package family name in the line this.inventoryService.PackageFamilyName = "replace with the package family name"; with the package family name of the AppServiceProvider project that you obtained above in Deploy the service app and get the package family name.

最初に、コードによってアプリ サービスとの接続が確立されます。The code first establishes a connection with the app service. 接続は、this.inventoryService を破棄するまで開いたままになります。The connection will remain open until you dispose this.inventoryService. アプリ サービス名は、AppServiceProvider プロジェクトの Package.appxmanifest ファイルに追加した AppService Name 属性と一致する必要があります。The app service name must match the AppService Name attribute that you added to the AppServiceProvider project's Package.appxmanifest file. この例では <uap:AppService Name="com.microsoft.inventory"/> です。In this example, it is <uap:AppService Name="com.microsoft.inventory"/>.

message という名前の ValueSet が、アプリ サービスに送信するコマンドを指定するために作成されます。A ValueSet named message is created to specify the command that we want to send to the app service. この例のアプリ サービスでは、2 つのアクションのどちらを実行するかをコマンドが示すことを想定しています。The example app service expects a command to indicate which of two actions to take. クライアント アプリのテキスト ボックスからインデックスを取得し、Item コマンドでサービスを呼び出して項目の説明を取得します。We get the index from the textbox in the client app, and then call the service with the Item command to get the description of the item. その後、Price コマンドで呼び出しを行い、項目の価格を取得します。Then, we make the call with the Price command to get the item's price. ボタンのテキストは結果に設定されています。The button text is set to the result.

オペレーティング システムがアプリ サービスに呼び出しを接続できたかどうかを示すのは AppServiceResponseStatus のみです。このため、アプリ サービスが要求を満たすことができたことを確認するために、アプリ サービスから受け取る ValueSetStatus キーをチェックします。Because AppServiceResponseStatus only indicates whether the operating system was able to connect the call to the app service, we check the Status key in the ValueSet we receive from the app service to ensure that it was able to fulfill the request.

  1. Visual Studio で、ClientApp プロジェクトをソリューション エクスプローラー ウィンドウで、スタートアップ プロジェクトとなるように設定し、プロジェクトを実行します。In Visual Studio, set the ClientApp project to be the startup project in the Solution Explorer window and run the solution. 数値 1 をテキスト ボックスに入力し、ボタンをクリックします。Enter the number 1 into the text box and click the button. サービスから "Chair : Price = 88.99" が返されます。You should get "Chair : Price = 88.99" back from the service.

    Chair : price = 88.99 を表示するサンプル アプリ

アプリ サービスの呼び出しが失敗した場合は、ClientApp で次のことを確認します。If the app service call fails, check the following in the ClientApp:

  1. インベントリ サービスの接続に割り当てられたパッケージ ファミリ名が、AppServiceProvider アプリのパッケージ ファミリ名と一致することを確認します。Verify that the package family name assigned to the inventory service connection matches the package family name of the AppServiceProvider app. button_Click()this.inventoryService.PackageFamilyName = "..."; をご覧ください。See: button_Click()this.inventoryService.PackageFamilyName = "...";).
  2. button_Click() で、インベントリ サービスの接続に割り当てられたアプリ サービス名が、AppServiceProvider の Package.appxmanifest ファイルのアプリ サービス名と一致することを確認します。In button_Click(), verify that the app service name that is assigned to the inventory service connection matches the app service name in the AppServiceProvider's Package.appxmanifest file. this.inventoryService.AppServiceName = "com.microsoft.inventory"; をご覧ください。See: this.inventoryService.AppServiceName = "com.microsoft.inventory";.
  3. AppServiceProvider アプリが展開されたことを確認します (ソリューション エクスプローラーでソリューションを右クリックし、[展開] をクリックします)。Ensure that the AppServiceProvider app has been deployed (In the Solution Explorer, right-click the solution and choose Deploy).

アプリ サービスのデバッグDebug the app service

  1. サービスを呼び出す前にアプリ サービス プロバイダーのアプリが配置される必要があるため、ソリューションがデバッグする前に展開されるようにします。Ensure that the solution is deployed before debugging because the app service provider app must be deployed before the service can be called. (Visual Studio で、[ビルド] > [ソリューションの配置] の順にクリックします)。(In Visual Studio, Build > Deploy Solution).
  2. ソリューション エクスプローラーで、AppServiceProvider プロジェクトを右クリックして、[プロパティ] をクリックします。In the Solution Explorer, right-click the AppServiceProvider project and choose Properties. [デバッグ] タブで、[開始動作][起動しないが、開始時にマイ コードをデバッグする] に変更します。From the Debug tab, change the Start action to Do not launch, but debug my code when it starts. (C++ を使ってアプリ サービス プロバイダーを実装した場合、[デバッグ] タブから [アプリケーションの起動][いいえ] に変更します)。(Note, if you were using C++ to implement your app service provider, from the Debugging tab you would change Launch Application to No).
  3. MyAppService プロジェクトの Class1.cs ファイルで、OnRequestReceived() にブレークポイントを設定します。In the MyAppService project, in the Class1.cs file, set a breakpoint in OnRequestReceived().
  4. AppServiceProvider プロジェクトをスタートアップ プロジェクトとなるように設定し、F5 キーを押します。Set the AppServiceProvider project to be the startup project and press F5.
  5. (Visual Studio からではなく) [スタート] メニューから ClientApp を起動します。Start ClientApp from the Start menu (not from Visual Studio).
  6. 数値 1 をテキスト ボックスに入力し、ボタンを押します。Enter the number 1 into the text box and press the button. デバッガーは、アプリ サービス内のブレークポイントでアプリ サービスの呼び出しを停止します。The debugger will stop in the app service call on the breakpoint in your app service.

クライアントのデバッグDebug the client

  1. 前の手順に従って、アプリ サービスを呼び出すクライアントをデバッグします。Follow the instructions in the preceding step to debug the client that calls the app service.
  2. [スタート] メニューから ClientApp を起動します。Launch ClientApp from the Start menu.
  3. (ApplicationFrameHost.exe プロセスではなく) ClientApp.exe プロセスにデバッガーをアタッチします。Attach the debugger to the ClientApp.exe process (not the ApplicationFrameHost.exe process). (Visual Studio で、[デバッグ] > [プロセスにアタッチ] の順に選びます)。(In Visual Studio, choose Debug > Attach to Process....)
  4. ClientApp プロジェクトで、button_Click() にブレークポイントを設定します。In the ClientApp project, set a breakpoint in button_Click().
  5. ClientApp のテキスト ボックスに数値 1 を入力してボタンをクリックすると、クライアントとアプリ サービスの両方のブレークポイントがヒットするようになります。The breakpoints in both the client and the app service will now be hit when you enter the number 1 into the text box of the ClientApp and click the button.

一般的なアプリ サービスのトラブルシューティングGeneral app service troubleshooting

アプリ サービスに接続しようとして AppUnavailable 状態が発生した場合、以下を確認します。If you encounter a AppUnavailable status after trying to connect to an app service, check the following:

  • アプリ サービス プロバイダー プロジェクトとアプリ サービス プロジェクトが展開されていることを確認します。Ensure that the app service provider project and app service project are deployed. クライアントを実行する前に、両方が展開されている必要があります。展開されていない場合、クライアントには接続先がありません。Both need to be deployed before running the client because otherwise the client won't have anything to connect to. Visual Studio から [ビルド] > [ソリューションの配置] で展開できます。You can deploy from Visual Studio by using Build > Deploy Solution.
  • ソリューション エクスプローラーを使って、アプリ サービス プロバイダー プロジェクトで、アプリ サービスを実装したプロジェクトへの、プロジェクト間の参照が設定されていることを確認します。In the solution explorer, ensure that your app service provider project has a project-to-project reference to the project that implements the app service.
  • <Extensions> エントリとその子要素が、アプリ サービス プロバイダー プロジェクトに属する Package.appxmanifest ファイルに追加されていることを確認します。詳しくは上述の「package.appxmanifest へのアプリ サービスの拡張機能の追加」をご覧ください。Verify that the <Extensions> entry, and its child elements, have been added to the Package.appxmanifest file belonging to the app service provider project as specified above in Add an app service extension to package.appxmanifest.
  • アプリ サービス プロバイダーを呼び出すクライアントの AppServiceConnection.AppServiceName 文字列が、アプリ サービス プロバイダー プロジェクトの Package.appxmanifest ファイルで指定された <uap3:AppService Name="..." /> と一致していることを確認します。Ensure that the AppServiceConnection.AppServiceName string in your client that calls the app service provider matches the <uap3:AppService Name="..." /> specified in the app service provider project's Package.appxmanifest file.
  • AppServiceConnection.PackageFamilyName が、アプリ サービス プロバイダーのコンポーネントのパッケージ ファミリ名と一致していることを確認します。詳しくは上述の「package.appxmanifest へのアプリ サービスの拡張機能の追加」をご覧ください。Ensure that the AppServiceConnection.PackageFamilyName matches the package family name of the app service provider component as specified above in Add an app service extension to package.appxmanifest
  • この例のようなアウトプロセスのアプリ サービスでは、アプリ サービス プロバイダー プロジェクトの Package.appxmanifest ファイルの <uap:Extension ...> 要素で指定された EntryPoint が、アプリ サービス プロジェクトで IBackgroundTask を実装する公開クラスの名前空間とクラスの名前と一致していることを検証します。For out-of-proc app services such as the one in this example, validate that the EntryPoint specified in the <uap:Extension ...> element of your app service provider project's Package.appxmanifest file matches the namespace and class name of the public class that implements IBackgroundTask in your app service project.

デバッグのトラブルシューティングTroubleshoot debugging

アプリ サービス プロバイダーまたはアプリ サービス プロジェクトのブレークポイントでデバッガーが停止しない場合は、以下を確認します。If the debugger does not stop at breakpoints in your app service provider or app service projects, check the following:

  • アプリ サービス プロバイダー プロジェクトとアプリ サービス プロジェクトが展開されていることを確認します。Ensure that the app service provider project and app service project are deployed. クライアントを実行する前に、両方が展開されている必要があります。Both need to be deployed before running the client. Visual Studio から [ビルド] > [ソリューションの配置] で展開できます。You can deploy them from Visual Studio by using Build > Deploy Solution.
  • デバッグするプロジェクトがスタートアップ プロジェクトとして設定されていることを確認します。そのプロジェクトのデバッグ プロパティを確認し、F5 キーが押されたときにプロジェクトを実行しないように設定されていることを確認します。Ensure that the project you want to debug is set as the startup project and that the debugging properties for that project are set to not run the project when F5 is pressed. プロジェクトを右クリックし、[プロパティ][デバッグ] (または C++ では [デバッグ]) の順にクリックします。Right-click the project, then click Properties, and then Debug (or Debugging in C++). C# では、[開始動作][起動しないが、開始時にマイ コードをデバッグする] に設定します。In C#, change the Start action to Do not launch, but debug my code when it starts. C++ では、[アプリケーションの起動][いいえ] に設定します。In C++, set Launch Application to No.

注釈Remarks

この例では、バックグラウンド タスクとして実行されるアプリ サービスを作成して、それを別のアプリから呼び出す概要を示しています。This example provides an introduction to creating an app service that runs as a background task and calling it from another app. 重要な点は、アプリ サービスをホストするためのバックグラウンド タスクの作成、アプリ サービス プロバイダーのアプリの Package.appxmanifest ファイルへの windows.appservice 拡張機能の追加、クライアント アプリから接続するためのアプリ サービス プロバイダーのアプリのパッケージ ファミリ名の取得、アプリ サービス プロバイダー プロジェクトからアプリ サービス プロジェクトへのプロジェクト間の参照の追加、Windows.ApplicationModel.AppService.AppServiceConnection を使ったサービスの呼び出しです。The key things to note are the creation of a background task to host the app service, the addition of the windows.appservice extension to the app service provider app's Package.appxmanifest file, obtaining the package family name of the app service provider app so that we can connect to it from the client app, adding a project-to-project reference from the app service provider project to the app service project, and using Windows.ApplicationModel.AppService.AppServiceConnection to call the service.

MyAppService の完全なコードFull code for MyAppService

using System;
using Windows.ApplicationModel.AppService;
using Windows.ApplicationModel.Background;
using Windows.Foundation.Collections;

namespace MyAppService
{
    public sealed class Inventory : IBackgroundTask
    {
        private BackgroundTaskDeferral backgroundTaskDeferral;
        private AppServiceConnection appServiceconnection;
        private String[] inventoryItems = new string[] { "Robot vacuum", "Chair" };
        private double[] inventoryPrices = new double[] { 129.99, 88.99 };

        public void Run(IBackgroundTaskInstance taskInstance)
        {
            this.backgroundTaskDeferral = taskInstance.GetDeferral(); // Get a deferral so that the service isn't terminated.
            taskInstance.Canceled += OnTaskCanceled; // Associate a cancellation handler with the background task.

            // Retrieve the app service connection and set up a listener for incoming app service requests.
            var details = taskInstance.TriggerDetails as AppServiceTriggerDetails;
            appServiceconnection = details.AppServiceConnection;
            appServiceconnection.RequestReceived += OnRequestReceived;
        }

        private async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
        {
            // Get a deferral because we use an awaitable API below to respond to the message
            // and we don't want this call to get cancelled while we are waiting.
            var messageDeferral = args.GetDeferral();

            ValueSet message = args.Request.Message;
            ValueSet returnData = new ValueSet();

            string command = message["Command"] as string;
            int? inventoryIndex = message["ID"] as int?;

            if (inventoryIndex.HasValue &&
                 inventoryIndex.Value >= 0 &&
                 inventoryIndex.Value < inventoryItems.GetLength(0))
            {
                switch (command)
                {
                    case "Price":
                        {
                            returnData.Add("Result", inventoryPrices[inventoryIndex.Value]);
                            returnData.Add("Status", "OK");
                            break;
                        }

                    case "Item":
                        {
                            returnData.Add("Result", inventoryItems[inventoryIndex.Value]);
                            returnData.Add("Status", "OK");
                            break;
                        }

                    default:
                        {
                            returnData.Add("Status", "Fail: unknown command");
                            break;
                        }
                }
            }
            else
            {
                returnData.Add("Status", "Fail: Index out of range");
            }

            await args.Request.SendResponseAsync(returnData); // Return the data to the caller.
            // Complete the deferral so that the platform knows that we're done responding to the app service call.
            // Note for error handling: this must be called even if SendResponseAsync() throws an exception.
            messageDeferral.Complete();
        }


        private void OnTaskCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
        {
            if (this.backgroundTaskDeferral != null)
            {
                // Complete the service deferral.
                this.backgroundTaskDeferral.Complete();
            }
        }
    }
}