在 Windows 应用 SDK 中创建和使用应用服务

应用服务允许应用向其他应用提供服务。 应用服务在单独的进程中作为后台任务运行,并公开请求/响应信道。 其他应用使用 AppServiceConnection 连接到服务。

Important

应用服务需要 MSIX 包标识。 提供方应用和消费者应用都必须打包。 未打包的桌面应用无法托管或连接到应用服务。

注释

Windows 应用 SDK应用只能将应用服务作为进程外后台任务托管。 Microsoft.UI.Xaml.Application不提供OnBackgroundActivated替代,而 ExtendedActivationKind 不包含应用服务激活类型,因此Windows 应用 SDK应用无法按照 UWP 应用可以的方式直接在其自己的进程中接收应用服务激活。 有关详细信息,请参阅不支持进程内应用服务

应用服务的工作原理

应用服务包括:

  1. 声明和实现服务的提供程序应用
  2. 连接到服务并发送请求的使用者应用

通信使用 ValueSet 对象进行请求和响应数据。

创建应用服务提供商

步骤 1:在清单中声明应用服务

向提供程序应用appService添加扩展Package.appxmanifest,并指定实现服务的后台任务项目的入口点:

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

步骤 2:实现服务

创建单独的Windows 运行时组件项目并实现IBackgroundTask。 后台任务在进程外运行,因此无论提供程序应用是使用 Windows 应用 SDK 还是 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();
    }
}

使用应用服务

在使用者应用中,创建 AppServiceConnection 并发送请求:

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();
}

Tip

通过在 PowerShell 中运行 Get-AppxPackage -Name *ProviderApp* 查找提供程序应用的 PackageFamilyName,或者检查该提供程序应用的包清单。

为什么服务必须在进程外运行

应用服务的后台任务始终在其自身的进程中运行(仅对于 UWP 提供程序,则在提供程序应用的进程中运行)。 对于 Windows 应用 SDK 提供程序应用程序,后台任务必须在进程外运行,因为没有受支持的方式让该应用自身的进程接收应用服务激活。 有关详细信息,请参阅 进程内应用服务不受支持