Search code examples
c#uwpbackgrounddesktop-bridge

Cant register background task


I have the following background task:

namespace Background
{
    public sealed class BackgroundTask : IBackgroundTask
    {
        private BackgroundTaskDeferral _deferral;

        public void Run(IBackgroundTaskInstance taskInstance)
        {
            //_deferral = taskInstance.GetDeferral();

        }

in a file called Task.cs (not that the filename matters).

The Background namespace is in my Solution, which contains a Packaging project, which contains an UWP solution which should launch the Backgroundtask:

private async void LaunchBackground()
{
    await BackgroundExecutionManager.RequestAccessAsync();

    var exampleTaskName = "Background";

    foreach (var taskA in BackgroundTaskRegistration.AllTasks)
    {
        if (taskA.Value.Name == exampleTaskName)
        {
            await new ApplicationTrigger().RequestAsync();
            break;
        }
    }

    var builder = new BackgroundTaskBuilder();

    builder.Name = exampleTaskName;
    builder.TaskEntryPoint = "Background.BackgroundTask";

    BackgroundTaskRegistration task = builder.Register();

    await new ApplicationTrigger().RequestAsync();
}

In the UWP and the Packaging project have the following declared in the manifest:

  <Extensions>
    <Extension Category="windows.backgroundTasks" EntryPoint="Background.BackgroundTask">
      <BackgroundTasks>
        <Task Type="systemEvent" />
      </BackgroundTasks>
    </Extension>
  </Extensions>

I could not add a reference to the background project in my packagin project, but did so in my UWP project.

Still, when I try to launch it, I get the following:

At: BackgroundTaskRegistration task = builder.Register(); System.ArgumentException: 'Value does not fall within the expected range.'

builder according to debug is - builder {Windows.ApplicationModel.Background.BackgroundTaskBuilder} Windows.ApplicationModel.Background.BackgroundTaskBuilder

Have I left something out, or why isn't it working?

Edit: After adding a trigger:

builder.SetTrigger(new SystemTrigger(SystemTriggerType.BackgroundWorkCostChange, false));

WhichI actually do not want, I get a new error:

At: await new ApplicationTrigger().RequestAsync(); System.Runtime.InteropServices.COMException: 'Error HRESULT E_FAIL has been returned from a call to a COM component.'


Solution

  • Try the following code , we should check for background task access permissions then Register the background task :

    var hasAccess = await BackgroundExecutionManager.RequestAccessAsync();
    if (hasAccess == BackgroundAccessStatus.DeniedBySystemPolicy 
        || hasAccess == BackgroundAccessStatus.DeniedByUser
        || hasAccess == BackgroundAccessStatus.Unspecified)
    {
        await new MessageDialog("ACCESS DENIED").ShowAsync();
        return;
    }
    
    /////////////////////begin registering bg task
    var task = new BackgroundTaskBuilder
    {
        Name = "Background",
        TaskEntryPoint = typeof(Background.BackgroundTask).ToString()
    };
    
    //Trigger is necessary for registering bg tasks but Conditions are  optional
    //set a trigger for your bg task to run 
    //for ex. below Trigger will run when toast Notifications (cleared, user pressed an action button and so on)
    ToastNotificationActionTrigger actiontrigger = new ToastNotificationActionTrigger();
    
    task.SetTrigger(actiontrigger);
    
    //Optional Conditions like Internet Connection
    //var condition = new SystemCondition(SystemConditionType.InternetAvailable);
    
    //task.AddCondition(condition);//set condition
    
    BackgroundTaskRegistration registration = task.Register();//Register the task
    

    Also we should check if background task is already running before Register it. Something like below code snippet:

    var isAlreadyRegistered = BackgroundTaskRegistration.AllTasks.Any(t => t.Value?.Name == "BackroundTask");
    if (isAlreadyRegistered)
    {
        foreach (var tsk in BackgroundTaskRegistration.AllTasks)
        {
            if (tsk.Value.Name == "BackroundTask")
            {
                tsk.Value.Unregister(true);
                break;
            }
        }
    }
    

    More information Create and register an out-of-process background task