Criar e consumir um serviço de aplicativo no SDK do Aplicativo Windows

Os serviços de aplicativo permitem que seu aplicativo forneça serviços para outros aplicativos. Um serviço de aplicativo é executado como uma tarefa em segundo plano em um processo separado e expõe um canal de comunicação de solicitação/resposta. Outros aplicativos se conectam ao serviço usando AppServiceConnection.

Importante

Os serviços de aplicativo exigem a identidade do pacote MSIX. Os aplicativos do provedor e do consumidor devem ser empacotados. Aplicativos de área de trabalho não empacotados não podem hospedar nem se conectar a serviços de aplicativo.

Note

Os aplicativos do SDK do Aplicativo Windows podem hospedar um serviço de aplicativo apenas como uma tarefa em segundo plano fora do processo. Microsoft.UI.Xaml.Application não fornece uma sobrescrita OnBackgroundActivated, e ExtendedActivationKind não inclui um tipo de ativação de serviço de aplicativo; portanto, um aplicativo SDK do Aplicativo Windows não pode receber ativação de serviço de aplicativo diretamente em seu próprio processo como um aplicativo UWP poderia. Consulte Não há suporte para serviços de aplicativo no processo para obter detalhes.

Como funcionam os serviços de aplicativo

Um serviço de aplicativo consiste em:

  1. Um aplicativo de provedor que declara e implementa o serviço.
  2. Um aplicativo de consumidor que se conecta ao serviço e envia solicitações.

A comunicação usa objetos ValueSet para dados de solicitação e resposta.

Criar o provedor de serviços de aplicativo

Etapa 1: Declarar o serviço de aplicativo no manifesto

Adicione uma extensão appService ao aplicativo provedor Package.appxmanifest e especifique o ponto de entrada do projeto de tarefa em segundo plano que implementa o serviço:

<Extensions>
  <uap:Extension Category="windows.appService">
    <uap:AppService Name="com.example.myappservice"
                    EntryPoint="MyAppService.ServiceTask" />
  </uap:Extension>
</Extensions>

Etapa 2: Implementar o serviço

Crie um projeto de componente Windows Runtime separado e implemente IBackgroundTask. A tarefa em segundo plano é executada fora do processo, portanto, esse padrão funciona se o aplicativo provedor é criado com o SDK do Aplicativo Windows ou UWP:

// MyAppService.ServiceTask, in a separate Windows Runtime Component project
public sealed class ServiceTask : IBackgroundTask
{
    private BackgroundTaskDeferral _deferral;

    public void Run(IBackgroundTaskInstance taskInstance)
    {
        _deferral = taskInstance.GetDeferral();
        taskInstance.Canceled += OnTaskCanceled;

        var details = taskInstance.TriggerDetails as AppServiceTriggerDetails;
        if (details != null)
        {
            details.AppServiceConnection.RequestReceived += OnRequestReceived;
        }
    }

    private async void OnRequestReceived(AppServiceConnection sender,
        AppServiceRequestReceivedEventArgs args)
    {
        var deferral = args.GetDeferral();
        var response = new ValueSet();
        response.Add("result", "Hello from the service!");
        await args.Request.SendResponseAsync(response);
        deferral.Complete();
    }

    private void OnTaskCanceled(IBackgroundTaskInstance sender,
        BackgroundTaskCancellationReason reason)
    {
        _deferral?.Complete();
    }
}

Consumir o serviço de aplicativo

No aplicativo do consumidor, crie uma solicitação AppServiceConnection e envie:

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

private async Task CallAppServiceAsync()
{
    var connection = new AppServiceConnection
    {
        AppServiceName = "com.example.myappservice",
        PackageFamilyName = "ProviderApp_1234567890abc"
    };

    var status = await connection.OpenAsync();
    if (status != AppServiceConnectionStatus.Success)
    {
        // Handle connection failure
        return;
    }

    var request = new ValueSet
    {
        { "command", "add" },
        { "a", 5 },
        { "b", 3 }
    };

    var response = await connection.SendMessageAsync(request);
    if (response.Status == AppServiceResponseStatus.Success)
    {
        int result = (int)response.Message["result"];
        // result is 8
    }

    connection.Dispose();
}

Dica

Encontre o PackageFamilyName do aplicativo do provedor executando Get-AppxPackage -Name *ProviderApp* no PowerShell ou verifique o manifesto do pacote do aplicativo do provedor.

Por que o serviço deve ser executado fora do processo principal

A tarefa em segundo plano de um serviço de aplicativo sempre é executada em seu próprio processo (ou no processo do aplicativo provedor, somente para provedores UWP). Para um aplicativo provedor do SDK do Aplicativo Windows, a tarefa em segundo plano deve ser executada fora do processo, porque não há nenhuma forma com suporte para que o processo do próprio aplicativo receba a ativação por serviço de aplicativo. Para obter mais informações, consulte Não há suporte para serviços de aplicativo no processo.