One of the common requirements that many traditional desktop apps have is to support the “launch at startup” option: when the user logs in into his Windows PC, the application is automatically started, without requiring him to manually open it. It’s a way to speed up the workflow of the user and it’s leveraged especially by communications apps (like Skype, Slack, Telegram, Microsoft Teams, etc.), so that the user can be immediately connected with his friends and colleagues right after booting up his computer.
Is it possible to support this requirement also in a converted desktop app with the Desktop Bridge? Sure, thanks to one of the many special extensions that are available specifically for converted apps.
For this post, we’re going to take as a starting point the usual sample app I’ve used in every other blog post ( HelloCentennial ) and expand it to add this feature. You can grab, as usual, the original version of the project from my GitHub repository: https://github.com/qmatteoq/DesktopBridge/tree/master/1.%20Desktop%20App%20Converter/HelloCente...
In this case, to achieve our goal, we’re going to leverage the classic manual approach based on the Desktop Bridge Debugging Project for Visual Studio 2017. As such, our starting point will be the same you can find in this folder of my repository: https://github.com/qmatteoq/DesktopBridge/tree/master/3.%20Convert
Here is how the solution looks like:
As for every other extension, the starting point is always the manifest file. To add support to the “launch at startup” option, we need to leverage a feature called Startup Task , which must be added to the AppxManifest.xml file included in the PackageFiles folder of the Desktop Bridge Debugging Project. Here is how the extension definition looks like:<Extensions>
The extension is part of a specific set reserved for desktop apps so, in the Package entry of the manifest, you need to add the desktop namespace, as in the following sample:<?xml version="1.0" encoding="utf-8"?>
The <desktop:Extension > element has two fixed attributes:
The custom attribute is Excecutable , which is a reference to the process that you want to launch at startup. In this case, it’s the same process of the main app ( HelloCentennial.exe ), but it isn’t a fixed requirement: it can be a different executable stored inside the same app package or you can even have multiple entries, in case you have multiple processes you need to run at startup.
Inside the <desktop:Extension> entry you need to define the real task, thanks to the <desktop:StartupTask> element. Here you can configure a set of important attributes:
This is how the full AppxManifest.xml file of our converted app looks like:<?xml version="1.0" encoding="utf-8"?>
This is enough to enable the feature: launch the converted version of the app by setting, as startup project in is Visual Studio, the Desktop Bridge Debugging one and press F5. If you did everything correctly, your app will be now automatically enabled for startup: you can easily check it by right clicking on the taskbar in Windows, choosing Task Manager and move to the Startup tab. You should find your converted app in the list of apps that are allowed to run at startup:
There’s one important information to highlight: in order for the startup task to be properly registered, the app needs to be launched at least one time. It isn’t enough to side load the AppX or install the app from the Store to schedule the startup task.
Having only the opportunity to define a startup task without giving the chance to the user or to the developer to control it wouldn’t be really useful: typically, all the traditional desktop apps that support this feature offer also a setting so that the user can control it and enable / disable the auto startup. We can achieve this goal thanks to a specific set of APIs which are part of the Universal Windows Platform. As such, if we want to include this feature in our converted app, we need to move to the Enhance phase: you can refer to one of the previous posts on this blog to learn how you can integrate UWP APIs inside a traditional desktop application.
Once you have added a reference to the required libraries (either by manually adding a reference to the Windows.md and System.Runtime.WindowsRuntime files or by using the UWPDesktop NuGet package ), you can access to the StartupTask class, which belongs to the Windows.ApplicationModel namespace. Let’s assume that we have modified the user interface of the basic HelloCentennial app to add a CheckBox control that reflects the status of the startup task: when it’s checked, the task is enabled and the application is launched at startup; when it’s unchecked, the task is disabled. This is the look and feel of the updated user interface:
As first step, I’ve subscribed to the Load event of the form, so that I can check the status of the task when the app starts and keep the user interface consistent:private async void Form1_Load(object sender, EventArgs e)
Looking at the code, you’ll now understand the importance of the TaskId attribute of the <desktop:StartupTask> element in the manifest file: to get a reference in code to the startup task, we need to call the GetAsync() method of the StartupTask class passing, as parameter, the identifier we have declared in the manifest. Then we can use the State enumerator to understand which is the current status:
By using the same APIs, we can now allow the user to control the startup behavior: once we have a reference to the startup task object, in fact, we have access to some APIs to enable or disable it. The following sample shows the code that handles the Click event of the CheckBox control, which is invoked every time the user clicks on it:private async void chkBoxStartup_Click(object sender, EventArgs e)
We get a reference to the startup task we have declared in the manifest identified by the HelloCentennialTask name. Then, by using again the State property, we check if the task is already enabled or not:
That’s all. If you now try to launch again the application, the checkbox will be selected: we have queried the status of the task, we have found out that it’s enabled and we have checked it. If you click on it to uncheck it, you’ll invoke the chkBoxStartup_Click event handler, which will call the Disable() method. Again, you can see the outcome by right clicking on the Windows taskbar and opening the Task Manager: this time, in the Startup section, you should see that the status of the task connected to the Hello Centennial app will be Disabled .
Let’s do another experiment. Enable the task again by clicking on the checkbox, then close the application. Now, in the Startup section of the Task Manager, right click on the Hello Centennial task and choose Disable . Now reopen the app: this time, the checkbox will be unchecked, since during the form load the StartupTask API will detect that the task status is DisabledByUser . Now click on the checkbox: this time you’ll get a message saying that the task has been disabled by the user and the checkbox will stay unchecked. This is expected: the task has been disabled by the user directly in Windows, so the app can’t enable it again on its own. It must be the user to return to the Task Manager, go to the Startup section, right click on the Hello Centennial startup task and choose Enable . Now the application will be able to control it again and you’ll be able to use the checkbox to enable or disable it.
In this post we’ve learned how to enable a “launch at startup” experience also in a converted desktop app with the Desktop Bridge. As usual, you can find the sample used in this blog post on my GitHub repository at https://github.com/qmatteoq/DesktopBridge/tree/master/Extras/StartupTask
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.