How to use the ServicingComplete trigger (XAML)

[This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation]

Learn how to use the **ServicingCompleteSystemTrigger to control background task registration after app updates.

What you need to know

Technologies

Prerequisites

Instructions

Step 1: Create a ServicingComplete background task

Background task registrations persist across app updates. If an app is updated, its registrations continue to be valid and will be triggered. An app can register a background task with the ServicingComplete trigger to be notified when the app is updated, and unregister background tasks that are no longer valid.

  1. Create a new class that implements the IBackgroundTask interface, as with any other background task.

    Note  In C#, the background task class itself - and all other classes in the background task project - need to be public sealed classes.

    The following sample code shows a basic starting point for a background task:

    // 
    // ExampleBackgroundTask.cs
    // 
    
    using Windows.ApplicationModel.Background;
    
    namespace Tasks
    {
        public sealed class ServicingCompleteTask : IBackgroundTask
        {
            public void Run(IBackgroundTaskInstance taskInstance)
            {
    
            }
        }
    }
    
    // 
    // ServicingCompleteTask.cpp
    // 
    
    #include "pch.h"
    #include "ServicingCompleteTask.h"
    
    using namespace Tasks;
    using namespace Windows::ApplicationModel::Background;
    
    void ServicingCompleteTask::Run(IBackgroundTaskInstance^ taskInstance)
    {
    
    }
    
  2. Find the registration object for the background task that needs to be unregistered. Call Unregister to unregister the task. Note that you can force the background task to stop running (if an instance is active) by setting the cancelTask parameter to true.

    The following example shows how to unregister tasks from the ServicingComplete task:

    // 
    // ExampleBackgroundTask.cs
    // 
    
    using Windows.ApplicationModel.Background;
    
    namespace Tasks
    {
        public sealed class ServicingCompleteTask : IBackgroundTask
        {
            public void Run(IBackgroundTaskInstance taskInstance)
            {
                // 
                // Unregister tasks that no longer exist.
                // 
    
                string unregisterTask = "BadTaskName";
    
                var task = FindTask(unregisterTask);
                if (task != null)
                {
                    task.Unregister(true);
                }
            }
    
    
            // 
            // Check for a registration of the named background task. If one
            // exists, return it.
            // 
            public static BackgroundTaskRegistration FindTask(string taskName)
            {
                foreach (var cur in BackgroundTaskRegistration.AllTasks)
                {
                    if (cur.Value.Name == taskName)
                    {
                        // 
                        // The task is registered.
                        // 
    
                        return (BackgroundTaskRegistration)(cur.Value);
                    }
                }
    
                return null;
            }
    
        }
    }
    
    // 
    // ServicingCompleteTask.cpp
    // 
    
    #include "pch.h"
    #include "ServicingCompleteTask.h"
    
    using namespace Tasks;
    using namespace Windows::ApplicationModel::Background;
    
    
    void ServicingCompleteTask::Run(IBackgroundTaskInstance^ taskInstance)
    {
        // 
        // Unregister tasks that no longer exist.
        // 
    
        Platform::String ^ unregisterTask = "BadTaskName";
    
        BackgroundTaskRegistration ^ unregTask = FindTask(unregisterTask);
    
        if (unregTask != nullptr)
        {
            unregTask->Unregister(true);
        }
    }
    
    
    // 
    // Check for a registration of the named background task. If one exists,
    // return it.
    // 
    BackgroundTaskRegistration ^ 
                        ServicingCompleteTask::FindTask(Platform::String ^ taskName)
    {
        auto iter   = BackgroundTaskRegistration::AllTasks->First();
        auto hascur = iter->HasCurrent;
    
        while (hascur)
        {
            auto cur = iter->Current->Value;
    
            if(cur->Name == taskName)
            {
                // 
                // The task is registered.
                // 
    
                return (BackgroundTaskRegistration ^)(cur);
            }
    
            hascur = iter->MoveNext();
        }
    
        return nullptr;
    }
    
  3. Register replacement tasks as appropriate. Use a background task registration function, like the one specified in How to register a background task, to simplify the work.

    The following code concludes the example by adding capability of registering a new background task:

    // 
    // ExampleBackgroundTask.cs
    // 
    
    using Windows.ApplicationModel.Background;
    
    namespace Tasks
    {
        public sealed class ServicingCompleteTask : IBackgroundTask
        {
            public void Run(IBackgroundTaskInstance taskInstance)
            {
                // 
                // Unregister tasks that no longer exist.
                // 
    
                string unregisterTask = "BadTaskName";
    
                var task = FindTask(unregisterTask);
                if (task != null)
                {
                    task.Unregister(true);
                }
    
                // 
                // Register new/replacement tasks.
                // 
    
                string newTaskName = "NewTask";
                string newTaskEntryPoint = "Tasks.NewTask";
    
                SystemTrigger internetTrigger =
                      new SystemTrigger(SystemTriggerType.InternetAvailable, false);
    
                var newTask = RegisterBackgroundTask(newTaskEntryPoint,
                                                     newTaskName, 
                                                     internetTrigger, 
                                                     null);
            }
    
    
            // 
            // Check for a registration of the named background task. If one exists,
            // return it.
            // 
            public static BackgroundTaskRegistration FindTask(string taskName)
            {
                foreach (var cur in BackgroundTaskRegistration.AllTasks)
                {
                    if (cur.Value.Name == taskName)
                    {
                        // 
                        // The task is registered.
                        // 
    
                        return (BackgroundTaskRegistration)cur.Value;
                    }
                }
    
                return null;
            }
        }
    }
    
    // 
    // ServicingCompleteTask.cpp
    // 
    
    #include "pch.h"
    #include "ServicingCompleteTask.h"
    
    using namespace Tasks;
    using namespace Windows::ApplicationModel::Background;
    
    
    void ServicingCompleteTask::Run(IBackgroundTaskInstance^ taskInstance)
    {
        // 
        // Unregister tasks that no longer exist.
        // 
    
        Platform::String ^ unregisterTask = "BadTaskName";
    
        BackgroundTaskRegistration ^ unregTask = FindTask(unregisterTask);
    
        if (unregTask != nullptr)
        {
            unregTask->Unregister(true);
        }
    
    
        // 
        // Register new/replacement tasks.
        // 
    
        Platform::String ^ newTaskName = "NewTask";
        Platform::String ^ newTaskEntryPoint = "Tasks.NewTask";
    
        SystemTrigger ^ internetTrigger = 
                 ref new SystemTrigger(SystemTriggerType::InternetAvailable, false);
    
        BackgroundTaskRegistration ^ newTask =
                                          RegisterBackgroundTask(newTaskEntryPoint, 
                                                                 newTaskName,
                                                                 internetTrigger, 
                                                                 nullptr);
    }
    
    
    // 
    // Check for a registration of the named background task. If one exists,
    // return it.
    // 
    BackgroundTaskRegistration ^
                        ServicingCompleteTask::FindTask(Platform::String ^ taskName)
    {
        auto iter   = BackgroundTaskRegistration::AllTasks->First();
        auto hascur = iter->HasCurrent;
    
        while (hascur)
        {
            auto cur = iter->Current->Value;
    
            if(cur->Name == taskName)
            {
                // 
                // The task is registered.
                // 
    
                return (BackgroundTaskRegistration ^)(cur);
            }
    
            hascur = iter->MoveNext();
        }
    
        return nullptr;
    }
    

Step 2: Register the ServicingComplete background task

The ServicingComplete background task should be registered along with other background tasks, so that it can be triggered when the app is updated. The entry point for the ServicingComplete background task must remain the same in the app update.

  1. Create a new SystemTrigger object:

    • The first parameter, triggerType, should be set to servicingComplete.

    • The second parameter, OneShot, should be set to false.

    This example code creates a ServicingComplete trigger:

    SystemTrigger servicingCompleteTrigger =
                      new SystemTrigger(SystemTriggerType.ServicingComplete, false);
    
    SystemTrigger ^ servicingCompleteTrigger =
                 ref new SystemTrigger(SystemTriggerType::ServicingComplete, false);
    

    Note  Adding a condition to a ServicingComplete background task trigger is not recommended.

     

  2. Call your background task registration function to register the task. For more information on registering background tasks, see How to register a background task.

    The following code registers the ServicingComplete task:

    string entryPoint = "Tasks.ServicingCompleteTask";
    string taskName = "ServicingComplete background task";
    
    BackgroundTaskRegistration task = RegisterBackgroundTask(entryPoint, 
                                                          taskName, 
                                                          servicingCompleteTrigger,
                                                          null);
    
    Platform::String ^ entryPoint = "Tasks.ServicingCompleteTask";
    Platform::String ^ taskName   = "ServicingComplete background task";
    
    BackgroundTaskRegistration ^ task = RegisterBackgroundTask(entryPoint,
                                                          taskName,
                                                          servicingCompleteTrigger,
                                                          nullptr);
    

    Note  On Windows Phone, you must call RequestAccessAsync once before registering any background tasks.

Step 3: Declare the background task in the package manifest

The ServicingComplete background task needs to be listed in the package manifest, just like any other background task. For more info see How to declare background tasks in the application manifest. For example:

Remarks

See How to debug a background task (Windows Store apps) for important info related to debugging app updates with background tasks.

Quickstart: Create and register a background task

How to register a background task

How to respond to system events with background tasks

How to set conditions for running a background task

How to declare background tasks in the application manifest

How to debug a background task

Guidelines and checklists for background tasks