Testing Pre-Install Task on UWP Apps

Microsoft provides an entry point to execute UWP app’s code even before the application is opened by the user. The entry point is available through background task component which can be triggered during deployment task. There are two deployments task types available to UWP: PreInstallConfigTask and UpdateTask.

In this article I will guide you on how to incorporate and test PreInstallConfigTask in your application. Note that PreInstallConfigTask is only available for pre-installed application.

Clone https://github.com/pradithya/UwpSamplePreInstalledApp for the sample code.

I created a background task (Windows Runtime Component) with name BackgroundTask.PreInstalledTask. The background task will only display a toast notification with pre-defined text information.

namespace BackgroundTask
{
    public sealed class PreInstalledTask : IBackgroundTask
    {
        public void Run(IBackgroundTaskInstance taskInstance)
        {
            ToastHelper.PopToast("Pre-Install Task", "Pre install task is running", "OK");
        }
    }
}

Add pre-installed task capability to the main application’s app manifest and hook it to the background task.

preinstall

Now the application is ready and we can test it.
Create application package for testing (see how).
Once the app package is created, open PowerShell as Administrator and enter the following command.

Add-AppxProvisionedPackage -Online -PackagePath [*appx / *appxbundle path] -SkipLicense

This command will use DISM to include the application into current Windows image. In the same time, the deployment of the application for the current user will be done and the pre-install task will also be triggered. In this application context, the task will display toast notification as shown below.

preinstall

As the application become the part of Windows image, every time you create a new user the application will be available as a pre-installed app. To revert this behavior you’ll need to remove all of the application instances in each user and execute following command in Powershell.

Remove-AppxProvisionedPackage -online -packagename TestPreInstalledApp_1.0.0.0_neutral_~_yzekw4x8qxe1g

source:
https://docs.microsoft.com/en-us/windows-hardware/customize/preinstall/preinstall-tasks
https://docs.microsoft.com/en-us/windows/uwp/publish/generate-preinstall-packages-for-oems
https://technet.microsoft.com/library/dn376490(v=wps.620).aspx

Advertisements

Macro Expansion

This bug made me spent half of my day. I have a macro to read a 32-bit data from either a virtual memory or RAM, depending on the address passed to a macro. More or less the code is as follow


#define read_u32(addr)    (if (is_addr_in_virtual(addr))?read_virtual_u32(addr):(*((u32 *) addr )) )

Did you see what is wrong?

Normally the macro works fine, let say we have a “ram_addr” which is an address in RAM and we pass it to the macro


var = read_u32(ram_addr)

//read_u32(ram_addr) will return 
var = (*((u32 *) ram_addr))


The problem happen when parameter passed is some short of operation like “base_addr + offset” where the macro expansion leads to a different behavior than expected.


var = read_u32(ram_addr + offset)

//read_u32(ram_addr + offset) will return
var = (*((u32 *) ram_addr + offset)

Let’s say that ram_addr is 0x0000A00 and offset is 2. What I want the macro to return is the u32 data in address 0x0000A02. But the expansion above, will return address 0x0000A08 since “ram_addr” is casted to (u32 *) before adding to “offset”.

The problem lies on the presence of parenthesis surrounding the macro parameter. The corrected version is as follow.

 
#define read_u32(addr)    (if (is_addr_in_virtual(addr))?read_virtual_u32(addr):(*((u32 *) (addr) )) ) 

This way, if I pass “ram_addr + offset” to the macro, the addition will take place first before the address is casted to (u32 *), and thus will return correct value.