You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UWP中如何用IBackgroundTask实现通知跳转至外部应用?

问题描述

我有两个UWP应用app1和app2,已经为app1实现了硬件变更触发的通知功能,代码如下:

private async void Hardware_Change(object sender, RoutedEventArgs e)
{
    var toastContentBuilder = new ToastContentBuilder()
        .AddArgument("action", "app2")
        .AddText("open hardware app")
        .AddText("Please Open Hardware App")
        .GetToastContent();
    var tost = new ToastNotification(toastContentBuilder.GetXml());
    ToastNotificationManager.CreateToastNotifier().Show(tost);
    Application.Current.Exit();
}

我创建了Windows Runtime Component项目实现IBackgroundTask,并在app1项目中引用该组件,代码如下:

public sealed class LancherBackgroundTask : IBackgroundTask
{
    public async void Run(IBackgroundTaskInstance taskInstance)
    {
            var uri = new Uri("app2:");
            var options = new LauncherOptions();
            options.TargetApplicationPackageFamilyName = "app2_packge_family_name";
            var success = await Launcher.LaunchUriAsync(uri, options);
    }
}

随后在app1的package.appmanifest中注册了该后台任务,配置如下:

<Extensions>
  <Extension Category="windows.backgroundTasks" EntryPoint="BackgroundHelper.LancherBackgroundTask">
    <BackgroundTasks>
      <Task Type="pushNotification"/>
    </BackgroundTasks>
  </Extension>
</Extensions>

目前遇到的问题:无法通过app1的通知启动app2,每次点击通知都会打开app1,且无法确认IBackgroundTask是否正常运行。

需要解决:如何在UWP中正确使用IBackgroundTask?以及如何实现点击app1的通知直接打开app2而不启动app1?

解决方案

一、修正后台任务的注册与触发逻辑

你当前注册的后台任务类型是pushNotification,但你的场景是Toast通知点击触发后台任务,需要做以下调整:

  1. 修改后台任务的注册类型
    在package.appmanifest中,将后台任务类型改为toastNotification,匹配Toast点击的触发场景:

    <Extensions>
      <Extension Category="windows.backgroundTasks" EntryPoint="BackgroundHelper.LancherBackgroundTask">
        <BackgroundTasks>
          <Task Type="toastNotification"/>
        </BackgroundTasks>
      </Extension>
    </Extensions>
    
  2. 为Toast通知绑定后台任务触发规则
    在显示Toast之前,必须将通知的激活类型设置为后台任务,否则点击会默认启动app1。修改Hardware_Change方法:

    private void Hardware_Change(object sender, RoutedEventArgs e)
    {
        var toastContentBuilder = new ToastContentBuilder()
            .AddArgument("action", "app2")
            .AddText("open hardware app")
            .AddText("Please Open Hardware App");
    
        // 设置Toast激活类型为后台任务
        var toastContent = toastContentBuilder.GetToastContent();
        toastContent.ActivationType = ToastActivationType.Background;
        
        var toast = new ToastNotification(toastContent.GetXml());
        // 指定要触发的后台任务入口点(必须与manifest中注册的完全一致)
        toast.ActivationArguments = "BackgroundHelper.LancherBackgroundTask";
        
        ToastNotificationManager.CreateToastNotifier().Show(toast);
        Application.Current.Exit();
    }
    

二、完善后台任务的实现逻辑

后台任务中必须处理异步操作的延迟,避免系统提前终止任务,同时添加异常捕获便于排查问题:

public sealed class LancherBackgroundTask : IBackgroundTask
{
    private BackgroundTaskDeferral _deferral; // 用于延迟任务结束,等待异步操作完成

    public async void Run(IBackgroundTaskInstance taskInstance)
    {
        _deferral = taskInstance.GetDeferral(); // 获取延迟对象
        try
        {
            // 解析Toast传递的参数,确认触发逻辑是否正确
            var triggerDetail = taskInstance.TriggerDetails as ToastNotificationActionTriggerDetail;
            if (triggerDetail != null)
            {
                var args = ToastArguments.Parse(triggerDetail.Argument);
                string action = args.Get("action");
                
                if (action == "app2")
                {
                    var uri = new Uri("app2:");
                    var options = new LauncherOptions();
                    // 替换为app2实际的包家族名称(可在app2的manifest打包页查看)
                    options.TargetApplicationPackageFamilyName = "app2_packge_family_name";
                    bool success = await Launcher.LaunchUriAsync(uri, options);
                    
                    // 可写入本地日志验证执行状态,例如写入LocalFolder下的日志文件
                }
            }
        }
        catch (Exception ex)
        {
            // 捕获异常并记录,方便排查启动失败或任务未执行的原因
        }
        finally
        {
            _deferral.Complete(); // 完成延迟,通知系统任务结束
        }
    }
}
  • 必须使用BackgroundTaskDeferral:异步操作未完成时,后台任务会被系统强制终止,这个对象能延长任务生命周期。
  • 添加参数解析和日志:可以明确任务是否触发、参数是否正确,便于调试。

三、验证后台任务是否运行

你可以通过两种方式确认任务执行状态:

  • 本地日志记录:在后台任务中写入日志到ApplicationData.Current.LocalFolder,之后打开app1读取日志文件查看执行情况。
  • Visual Studio调试:在调试菜单选择「其他调试目标」->「后台任务」,选择对应的LancherBackgroundTask设置断点,触发Toast点击后查看断点是否命中。

四、确保app2的协议注册正确

要通过app2:协议启动app2,必须在app2的package.appmanifest中注册该协议:

<Extensions>
  <uap:Extension Category="windows.protocol">
    <uap:Protocol Name="app2">
      <uap:DisplayName>App2 Protocol</uap:DisplayName>
    </uap:Protocol>
  </uap:Extension>
</Extensions>

同时确认app2的包家族名称正确:可在app2的manifest「打包」选项卡查看,或通过代码Package.Current.Id.FamilyName获取。

内容的提问来源于stack exchange,提问作者Shiva_Adasule

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 05:28:15