Book Image

Modernizing Your Windows Applications with the Windows App SDK and WinUI

By : Matteo Pagani, Marc Plogas
5 (1)
Book Image

Modernizing Your Windows Applications with the Windows App SDK and WinUI

5 (1)
By: Matteo Pagani, Marc Plogas

Overview of this book

If you're a developer looking to improve and modernize your existing LOB applications to leverage modern Windows features without having to rewrite the entire application from scratch, this book is for you. You’ll learn how to modernize your existing Windows Forms, WPF, and UWP applications and enrich them with the latest Windows features. Starting with sample LOB applications that cover common scenarios, you'll learn the differences between various components and then focus on design features for improved visual aspects like accessibility and responsive layouts. The book shows you how to enhance your existing applications using Windows App SDK components and various Windows APIs, resulting in deeper integration with the operating system. You’ll be taking a closer look at WinML, which enables Windows applications to evaluate machine learning models offline and leverage the power of your machine, or notifications, to engage with your users in a more effective way. You’ll also learn how to make your application deployment-ready by distributing it using various platforms like the Microsoft Store or websites. By the end of this Windows book, you'll be able to create a migration plan for your existing Windows applications and put your knowledge to work by enhancing your application with new features and integrating them with the Windows ecosystem.
Table of Contents (19 chapters)
1
Section 1: Basic Concepts
3
Section 2: Modernization Journey
9
Section 3: Integrating Your App with the Windows Ecosystem
14
Section 4: Distributing Your Application

Managing the dependency with the Windows App SDK

By detaching features and APIs from the operating system, the Windows team has gained a lot of benefits, such as the ability to add new features and fix issues outside the regular Windows update cycle. However, as developers, we cannot take for granted that the user who installs our application will have the Windows App SDK runtime installed on their machine. As such, it's our responsibility as developers to manage this dependency in the right way. This is one of the scenarios where the difference between adopting the packaged or unpackaged model is critical, since they adopt two different ways to deploy the dependency.

The Windows App SDK runtime is made up of the following components:

  • The framework package: This package contains the binaries that are used by the applications at runtime.
  • The main package: This package contains multiple out-of-process components that aren't included in the framework, such as background tasks, app extensions, and app services.
  • The singleton package: This package includes a long-running process that provides access to features that are shared across all applications, such as push notifications.
  • Dynamic Dependency Lifetime Manager (DDLM): This package is used to control the life cycle of the Windows App SDK runtime. Thanks to this package, Windows will refrain from automatically updating the runtime if one or more unpackaged apps that use the Windows App SDK are running.

Each of these components is stored in its own MSIX package. Let's see now how to manage the deployment of the runtime based on the way you distribute your application.

Packaged apps

As previously mentioned, packaged apps have a few advantages compared to unpackaged apps. Packaged applications are described by a manifest, which includes a section called Dependencies. This section is already used today to manage the dependency on a specific version of Windows or the Visual C++ runtime.

The dependency with the Windows App SDK runtime can be easily declared in the same section by adding the following entry:

<PackageDependency Name="Microsoft.WindowsAppRuntime.1.0" 
  MinVersion="0.319.455.0" Publisher="CN=Microsoft 
    Corporation, O=Microsoft Corporation, L=Redmond, 
      S=Washington, C=US" />

Thanks to this configuration, if the application is deployed to a machine that doesn't have the runtime installed, Windows will automatically download it from the Microsoft Store and install it system-wide so that future applications that you might install won't need to download it again.

In most cases, you won't have to manually include this entry. In fact, when you install the Windows App SDK NuGet package in your application, Visual Studio will add a special build task that will add this entry in the manifest for you every time you generate a new MSIX package.

However, there's still a manual requirement you have to take care of. As mentioned in the previous section, the Windows App SDK applications are dependent not just on the framework itself but, based on the features they use (for example, background tasks or push notifications), they might also need the main package and the singleton package. MSIX doesn't support having regular packages as dependencies, which means that when you deploy a packaged Windows App SDK application, the framework is automatically deployed if missing, but the other components aren't. However, these packages are included inside the framework and, as such, can be automatically deployed by using the DeploymentManager API, which belongs to the Microsoft.Windows.ApplicationModel.WindowsAppRuntime namespace. Thanks to this API, you can check whether one or more of the components are missing on the system and install them if necessary. This is an example implementation of the OnLaunched() method of a Windows App SDK application, which is executed when the application starts:

protected override void OnLaunched
  (Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
    var status = DeploymentManager.GetStatus();
    if (status.Status == 
      DeploymentStatus.PackageInstallRequired)
    {
        DeploymentManager.Initialize();
    }
    m_window = new MainWindow();
    m_window.Activate();
}

Thanks to the GetStatus() method, we can detect the status of the various components on the system. If one or more of them is missing (which is represented by the PackageInstallRequired value of the DeploymentStatus enumerator), we can call the Initialize() method to perform the deployment.

Unpackaged apps

For unpackaged apps, Microsoft provides an installer called WindowsAppRuntimeInstall.exe, which automatically detects the CPU architecture of a system (x86, x64, or ARM64) and installs system-wide the MSIX packages that compose the runtime – framework, main, and DDLM.

The installer also supports a --quiet parameter, which enables a silent installation with no user interaction and output messages. All the technologies and tools to create setup programs (or even just a PowerShell script) support the possibility of launching an executable as part of the installation, so it's easy to configure your installer to silently launch the WindowsAppRuntimeInstall.exe executable before or after the deployment of the main application, and before the whole installation process is completed.

Compared to a packaged application, you won't need to use the deployment APIs here, since the WindowsAppSDKInstall tool will take care of installing all the required packages on the system.

Upgrading the Windows App SDK runtime

The Windows App SDK runtime will continue to evolve over time, and as such, it's important for a developer to understand how future updates will be managed.

Updates can be delivered in two ways:

  • If the machine has access to Microsoft Store, they will be automatically downloaded and installed.
  • If the machine doesn't have access to Microsoft Store, it will be up to the application to include a newer version of the Windows App SDK runtime installer.

To control the way updates will be installed, the Windows App SDK has adopted the Semantic Versioning rules. By reading the official website (https://semver.org/), we learn that the version number is defined by three numbers, MAJOR.MINOR.PATCH, which stand for the following:

  • MAJOR is incremented when you make incompatible API changes.
  • MINOR is incremented when you add new functionality but with backward compatibility.
  • PATCH is increased when you make bug fixes that are backward-compatible.

The runtime installed on a machine will be automatically updated only if the MINOR or the PATCH revision changes. If a new release increases the MAJOR number, instead, it will be installed side by side with the existing ones. This makes sure that newer versions of the runtime that might include breaking changes won't replace the existing ones, causing your applications to stop working properly.

Thanks to the DDLM component of the runtime, Windows will keep the old instance of the runtime installed as long as there's at least one running application that is using it. Once the application is closed, the previous version of the runtime will be uninstalled, and at the next relaunch, the app will start using the updated version.

Now that we understand how to manage the Windows App SDK dependency in our application, we're ready to start creating our first application.