Extend your desktop application with modern UWP components

Some Windows 10 experiences (For example: a touch-enabled UI page) must run inside of a modern app container . If you want to add these experiences, extend your desktop application with UWP projects and Windows Runtime Components.

In many cases you can call UWP APIs directly from your desktop application, so before you review this guide, see Enhance for Windows 10.


This guide assumes that you've created a Windows app package for your desktop application by using the Desktop Bridge. If you haven't yet done this, see Desktop Bridge.

If you're ready, let's start.

First, setup your Solution

Add one or more UWP projects and runtime components to your solution.

Start with a solution that contains a Windows Application Packaging Project with a reference to your desktop application.

This image shows an example solution.

Extend start project

If your solution doesn't contain a packaging project, see Package your app by using Visual Studio.

Add a UWP project

Add a Blank App (Universal Windows) to your solution.

This is where you'll build a modern XAML UI or use APIs that run only within a UWP process.

UWP project

In your packaging project, right-click the Applications node, and then click Add Reference.

Reference UWP Project

Then, add a reference the UWP project.

Reference UWP Project

Your solution will look something like this:

Solution with UWP project

(Optional) Add a Windows Runtime Component

To accomplish some scenarios, you'll have to add code to a Windows Runtime Component.

runtime component app service

Then, from your UWP project, add a reference to the runtime component. Your solution will look something like this:

Runtime Component Reference

Let's take a look at a few things you can do with your UWP projects and runtime components.

Show a modern XAML UI

As part of your application flow, you can incorporate modern XAML-based user interfaces into your desktop application. These user interfaces are naturally adaptive to different screen sizes and resolutions and support modern interactive models such as touch and ink.

For example, with a small amount of XAML markup, you can give users with powerful map-related visualization features.

This image shows a Windows Forms application that opens a XAML-based modern UI that contains a map control.


The design pattern

To show a XAML-based UI, do these things:

1️⃣ Setup your Solution

2️⃣ Create a XAML UI

3️⃣ Add a protocol extension to the UWP project

4️⃣ Start the UWP app from your desktop app

5️⃣ In the UWP project, show the page that you want

Setup your Solution

For general guidance on how to set your solution up, see the First, setup your Solution section at the beginning of this guide.

Your solution would look something like this:

XAML UI Solution

In this example, the Windows Forms project is named Landmarks and the UWP project that contains the XAML UI is named MapUI.

Create a XAML UI

Add a XAML UI to your UWP project. Here's the XAML for a basic map.

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Margin="12,20,12,14">
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
    <maps:MapControl x:Name="myMap" Grid.Column="0" Width="500" Height="500"
                     ZoomLevel="{Binding ElementName=zoomSlider,Path=Value, Mode=TwoWay}"
                     Heading="{Binding ElementName=headingSlider,Path=Value, Mode=TwoWay}"
                     DesiredPitch="{Binding ElementName=desiredPitchSlider,Path=Value, Mode=TwoWay}"    
                     MapServiceToken="<Your Key Goes Here" />
    <Grid Grid.Column="1" Margin="12">
            <Slider Minimum="1" Maximum="20" Header="ZoomLevel" Name="zoomSlider" Value="17.5"/>
            <Slider Minimum="0" Maximum="360" Header="Heading" Name="headingSlider" Value="0"/>
            <Slider Minimum="0" Maximum="64" Header=" DesiredPitch" Name="desiredPitchSlider" Value="32"/>

Add a protocol extension

In Solution Explorer, open the package.appxmanifest file of the Packaging project in your solution, and add this extension.

  <uap:Extension Category="windows.protocol" Executable="MapUI.exe" EntryPoint="MapUI.App">
    <uap:Protocol Name="xamluidemo" />

Give the protocol a name, provide the name of the executable produced by the UWP project, and the name of the entry point class.

You can also open the package.appxmanifest in the designer, choose the Declarations tab, and then add the extension there.



Map controls download data from the internet so if you use one, you'll have to add the "internet client" capability to your manifest as well.

Start the UWP app

First, from your desktop application, create a Uri that includes the protocol name and any parameters you want to pass into the UWP app. Then, call the LaunchUriAsync method.

private void Statue_Of_Liberty_Click(object sender, EventArgs e)
    ShowMap(40.689247, -74.044502);

private async void ShowMap(double lat, double lon)
    string str = "xamluidemo://";

    Uri uri = new Uri(str + "location?lat=" +
        lat.ToString() + "&?lon=" + lon.ToString());

    var success = await Windows.System.Launcher.LaunchUriAsync(uri);


Parse parameters and show a page

In the App class of your UWP project, override the OnActivated event handler. If the app is activated by your protocol, parse the parameters and then open the page that you want.

protected override void OnActivated(Windows.ApplicationModel.Activation.IActivatedEventArgs e)
    if (e.Kind == ActivationKind.Protocol)
        ProtocolActivatedEventArgs protocolArgs = (ProtocolActivatedEventArgs)e;
        Uri uri = protocolArgs.Uri;
        if (uri.Scheme == "xamluidemo")
            Frame rootFrame = new Frame();
            Window.Current.Content = rootFrame;
            rootFrame.Navigate(typeof(MainPage), uri.Query);

Override the OnNavigatedTo method to use the parameters passed into the page. In this case, we'll use the latitude and longitude that were passed into this page to show a location in a map.

protected override void OnNavigatedTo(NavigationEventArgs e)
     if (e.Parameter != null)
         WwwFormUrlDecoder decoder = new WwwFormUrlDecoder(e.Parameter.ToString());

         double lat = Convert.ToDouble(decoder[0].Value);
         double lon = Convert.ToDouble(decoder[1].Value);

         BasicGeoposition pos = new BasicGeoposition();

         pos.Latitude = lat;
         pos.Longitude = lon;

         myMap.Center = new Geopoint(pos);

         myMap.Style = MapStyle.Aerial3D;



Similar Samples

Adding a UWP XAML user experience to VB6 Application

Northwind sample: End-to-end example for UWA UI & Win32 legacy code

Northwind sample: UWP app connecting to SQL Server

Provide services to other apps

You add a service that other apps can consume. For example, you can add a service that gives other apps controlled access to the database behind your app. By implementing a background task, apps can reach the service even if your desktop app is not running.

Here's a sample that does this.


Have a closer look at this app

✔️ Get the app

✔️ Browse the code

The design pattern

To show provide a service, do these things:

1️⃣ Implement the app service

2️⃣ Add an app service extension

3️⃣ Test the app service

Implement the app service

Here's where you'll validate and handle requests from other apps. Add this code to a Windows Runtime Component in your solution.

public sealed class AppServiceTask : IBackgroundTask
    private BackgroundTaskDeferral backgroundTaskDeferral;
    public void Run(IBackgroundTaskInstance taskInstance)
        this.backgroundTaskDeferral = taskInstance.GetDeferral();
        taskInstance.Canceled += OnTaskCanceled;
        var details = taskInstance.TriggerDetails as AppServiceTriggerDetails;
        details.AppServiceConnection.RequestReceived += OnRequestReceived;
    private async void OnRequestReceived(AppServiceConnection sender,
                                         AppServiceRequestReceivedEventArgs args)
        var messageDeferral = args.GetDeferral();
        ValueSet message = args.Request.Message;
        string id = message["ID"] as string;
        ValueSet returnData = DataBase.GetData(id);
        await args.Request.SendResponseAsync(returnData);
    private void OnTaskCanceled(IBackgroundTaskInstance sender,
                                BackgroundTaskCancellationReason reason)
        if (this.backgroundTaskDeferral != null)

Add an app service extension to the Packaging project

Open the package.appxmanifest file of the Packaging project, and add an app service extension to the <Application> element.

        <uap:AppService Name="com.microsoft.samples.winforms" />

Give the app service a name and provide the name of the entry point class. This is the class in which you implemented the service.

Test the app service

Test your service by calling it from another app. This code can be a desktop application such as a Windows forms app or another UWP app.


This code only works if you properly set the PackageFamilyName property of the AppServiceConnection class. You can get that name by calling Windows.ApplicationModel.Package.Current.Id.FamilyName in the context of the UWP project. See Create and consume an app service.

private async void button_Click(object sender, RoutedEventArgs e)
    AppServiceConnection dataService = new AppServiceConnection();
    dataService.AppServiceName = "com.microsoft.samples.winforms";
    dataService.PackageFamilyName = "Microsoft.SDKSamples.WinformWithAppService";
    var status = await dataService.OpenAsync();
    if (status == AppServiceConnectionStatus.Success)
        string id = int.Parse(textBox.Text);
        var message = new ValueSet();
        message.Add("ID", id);
        AppServiceResponse response = await dataService.SendMessageAsync(message);
        if (response.Status == AppServiceResponseStatus.Success)
            if (response.Message["Status"] as string == "OK")

Learn more about app services here: Create and consume an app service.

Similar Samples

App service bridge sample

App service bridge sample with C++ win32 app

MFC application that receives push notifications

Making your desktop application a share target

You can make your desktop application a share target so that users can easily share data such as pictures from other apps that support sharing.

For example, users could choose your app to share pictures from Microsoft Edge, the Photos app. Here's a WPF sample app that has that capability.

share target

Have a closer look at this app

✔️ Get the app

✔️ Browse the code

The design pattern

To make your application a share target, do these things:

1️⃣ Add a share target extension

2️⃣ Override the OnNavigatedTo event handler

Add a share target extension

In Solution Explorer, open the package.appxmanifest file of the Packaging project in your solution and add the extension.

            <uap:SupportsAnyFileType />

Provide the name of the executable produced by the UWP project, and the name of the entry point class. You'll also have to specify what types of files can be shared with your app.

Override the OnNavigatedTo event handler

Override the OnNavigatedTo event handler in the App class of your UWP project.

This event handler is called when users choose your app to share their files.

protected override async void OnNavigatedTo(NavigationEventArgs e)
  this.shareOperation = (ShareOperation)e.Parameter;
  if (this.shareOperation.Data.Contains(StandardDataFormats.StorageItems))
      this.sharedStorageItems =
        await this.shareOperation.Data.GetStorageItemsAsync();
      foreach (StorageFile item in this.sharedStorageItems)

Create a background task

You add a background task to run code even when the app is suspended. Background tasks are great for small tasks that don't require the user interaction. For example, your task can download mail, show a toast notification about an incoming chat message, or react to a change in a system condition.

Here's a WPF sample app that registers a background task.

background task

The task makes an http request and measures the time that it takes for the request to return a response. Your tasks will likely be much more interesting, but this sample is great for learning the basic mechanics of a background task.

Have a closer look at this app

✔️ Browse the code

The design pattern

To create a background service, do these things:

1️⃣ Implement the background task

2️⃣ Configure the background task

3️⃣ Register the background task

Implement the background task

Implement the background task by adding code to a Windows Runtime component project.

public sealed class SiteVerifier : IBackgroundTask
    public async void Run(IBackgroundTaskInstance taskInstance)

        taskInstance.Canceled += TaskInstance_Canceled;
        BackgroundTaskDeferral deferral = taskInstance.GetDeferral();
        var msg = await MeasureRequestTime();

    private async Task<string> MeasureRequestTime()
        string msg;
            var url = ApplicationData.Current.LocalSettings.Values["UrlToVerify"] as string;
            var http = new HttpClient();
            Stopwatch clock = Stopwatch.StartNew();
            var response = await http.GetAsync(new Uri(url));
            var elapsed = clock.ElapsedMilliseconds;
            msg = $"{url} took {elapsed.ToString()} ms";
        catch (Exception ex)
            msg = ex.Message;
        return msg;

Configure the background task

In the manifest designer, open the package.appxmanifest file of the Packaging project in your solution.

In the Declarations tab, add a Background Tasks declaration.

Background task option

Then, choose the desired properties. Our sample uses the Timer property.

Timer property

Provide the fully qualified name of the class in your Windows Runtime Component that implements the background task.

Timer property

Register the background task

Add code to your desktop application project that registers the background task.

public void RegisterBackgroundTask(String triggerName)
    var current = BackgroundTaskRegistration.AllTasks
        .Where(b => b.Value.Name == triggerName).FirstOrDefault().Value;

    if (current is null)
        BackgroundTaskBuilder builder = new BackgroundTaskBuilder();
        builder.Name = triggerName;
        builder.SetTrigger(new MaintenanceTrigger(15, false));
        builder.TaskEntryPoint = "HttpPing.SiteVerifier";
        System.Diagnostics.Debug.WriteLine("BGTask registered:" + triggerName);
        System.Diagnostics.Debug.WriteLine("Task already:" + triggerName);

Support and feedback

Find answers to your questions

Have questions? Ask us on Stack Overflow. Our team monitors these tags. You can also ask us here.

Give feedback or make feature suggestions

See UserVoice.