July 2017

Volume 32 Number 7

[Modern Apps]

Launch Other Applications from Your UWP App

By Frank La

Frank La VigneWindows has long provided the capability to programmatically launch applications from within another application. Indeed, it’s a feature common to practically any OS. The Universal Windows Platform (UWP) is no exception. In fact, the UWP adds a few new features. In this month’s column, I’ll explore the Launcher class and how to put it to use in your UWP apps.

In my last two columns, I wrote about exploring the rich functionality of the Bing Maps Control for UWP apps. There might be cases where you don’t need or wish to embed a rich mapping solution inside your UWP app. For those scenarios, you can leverage the built-in Maps app. This solution is ideal if you want to provide your users with mapping tools, but don’t wish to add complexity to your code base. Accomplishing this is easy with the Launcher class.

Use a Map Without Using a Map Control

Create a new blank UWP project in Visual Studio by choosing New Project from the File menu. Expand the Installed Templates | Windows | Blank App (Universal Windows). Name the project MapLauncher and then click OK. Immediately afterward, a dialog box will appear asking you which version of Windows the app should target. For this project, the default options will be fine, so you can just click OK. In the MainPage.xaml file, add the following XAML to create a button control:

<Button Name="btnLaunchMap" Click="btnLaunchMap_Click">Launch Map</Button>

In the MainPage.xaml.cs file, add the following code for the event handler:

private async void btnLaunchMap_Click(object sender, RoutedEventArgs e)

{

  Uri uri = new Uri("bingmaps:?rtp=adr.Washington,%20DC~adr.New%20York,

    %20NY&amp;mode=d&amp;trfc=1");

  await Launcher.LaunchUriAsync(uri);

}

Run the solution and click on the button. The Maps app should launch and display driving directions between Washington, D.C., and New York City along with traffic information, as shown in Figure 1.

Figure 1 Driving Directions Between New York City and Washington, D.C., in the Maps App

It’s quite impressive what can be done in so few lines of code. What, exactly, is going on here that made this so simple and why did the default Maps app automatically launch?

Protocol Launching

Protocol launching enabled launching the Maps app pre-populated with a route. Windows has always relied on file extensions and file-type associations to determine what applications should launch when a file is run. Starting with Windows 8, protocol launching was added to help facilitate launching apps with the option of passing along parameters.

Launching Apps via URI

Taking a closer look at the code in the previous sample, there’s something familiar about the line of code that creates a URI. The string passed to the URI constructor method follows a pattern familiar to Web developers, yet with a few differences.

Web addresses or, specifically, URIs, follow a pattern of [protocol]:[host address]?[parameter1]=[value1]& [parameter2]=[value2]. For instance, for the URI http://bing.com/search?q=franksworld, the protocol is HTTP, the host address is bing.com, and the value of “franksworld” is passed to the parameter “q.” The same holds true for the following URI, but with a few differences:

bingmaps:?rtp=adr.Washington,%20DC~adr.New%20York,%20NY&amp;mode=d&amp;trfc=1

Unlike HTTP or HTTPS, the protocol “bingmaps” is probably unfamiliar to most readers. Also, there’s no address for the resource. Interestingly, typing the this URI into the Edge browser will have the same effect, launching the Bing Maps app with the route between Washington, D.C., and New York City pre-populated. Additionally, the Run dialog, accessed by Windows key+R, will do the same if that URI is entered. Protocol activation is part of Windows 10 and may be leveraged outside of the UWP. In fact, Windows comes with a series of protocols already defined. The entire list can be found in Figure 2. Note that some of the protocols, like ms-call, may only be available on Windows Mobile.

Figure 2 Default Protocols in Windows

URI Scheme Launches
bingmaps:, ms-drive-to:, and ms-walk-to: Maps app
http: Default Web browser
mailto: Default e-mail app
ms-call: Call app
ms-chat: Messaging app
ms-people: People app
ms-settings: Settings app
ms-store: Store app
ms-tonepicker: Tone picker
ms-yellowpage: Nearby Numbers app

Passing Parameters

As for the Maps app, there’s any number of parameters to pass and the Maps app can be controlled to fit any app’s specific scenario. For instance, if the app needs to find pizza places in the Bronx, you’d simply use the following URI:

bingmaps:?q=pizza&amp;where=Bronx,NY 

Food Finder App

To demonstrate how to put parameters and protocol launching to practical use, create a new blank UWP project in Visual Studio. Name the project FoodFinder and click OK to create the app.

Add the XAML shown in Figure 3 to the MainPage.xaml file.

Figure 3 XAML Code to Create the UI

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

  <Grid.ColumnDefinitions>

    <ColumnDefinition Width="43*"/>

    <ColumnDefinition Width="137*"/>

  </Grid.ColumnDefinitions>

  <Grid.RowDefinitions>

    <RowDefinition Height="45*"/>

    <RowDefinition Height="44*"/>

    <RowDefinition Height="45*"/>

    <RowDefinition Height="45*"/>

    <RowDefinition Height="461*"/>

  </Grid.RowDefinitions>

  <TextBlock Margin="10" FontSize="24" Grid.RowSpan="5"

    Grid.ColumnSpan="2">Food Finder</TextBlock>

  <TextBlock Grid.Row="1" HorizontalAlignment="Right"

    VerticalAlignment="Center">Genre</TextBlock>

  <TextBlock Grid.Row="2" HorizontalAlignment="Right"

    VerticalAlignment="Center">Location</TextBlock>

  <ComboBox Name="cbxGenre" Grid.Row="1" Grid.Column="1"

    VerticalAlignment="Center" Margin="5" Width="212" SelectedIndex="0">

    <ComboBoxItem>Pizza</ComboBoxItem>

    <ComboBoxItem>BBQ</ComboBoxItem>

    <ComboBoxItem>Coffee</ComboBoxItem>

  </ComboBox>

  <TextBox Name="txtLocation" Grid.Row="2" Grid.Column="1"

    Margin="5"></TextBox>

  <CheckBox Name="ckbTraffic" Grid.Row="3" Grid.Column="1"

    Margin="5">Show Traffic</CheckBox>

  <StackPanel Orientation="Horizontal" Grid.Row="4"

    Grid.ColumnSpan="2" HorizontalAlignment="Center"

    VerticalAlignment="Top">

    <Button Name="btnLaunchMap" Click="btnLaunchMap_Click"

      Margin="5">Launch Map</Button>

    <Button Name="btnSearchMusic" Click="btnSearchMusic_Click"

      Margin="5">Search Music</Button>

  </StackPanel>

</Grid>

In the MainPage.xaml.cs file add the following code for the btnLaunchMap_Click event handler:

private async void btnLaunchMap_Click(object sender, RoutedEventArgs e)

{

  string genre = (cbxGenre.SelectedItem as ComboBoxItem).Content.ToString();

  string trafficValue = (ckbTraffic.IsChecked.Value) ? "1" : "0";

  string uriString = string.Format(

    $"bingmaps:?q={genre}&where={txtLocation.Text}&lvl=15&trfc={trafficValue}");

  Uri uri = new Uri(uriString);

  await Launcher.LaunchUriAsync(uri);

}

Run the project now. The interface should look similar to what’s shown in Figure 4. Pick a genre of food, enter a city into the Location textbox, and click Launch Map. The Maps app will launch and display a result set based on the inputs. Naturally, search results will vary based on the genre chosen and location entered. The final result should look something like Figure 5.

Figure 4 FoodFinder Interface

Figure 5 Results for Pizza in Bronx, N.Y.

Close the Maps app and go back to the FoodFinder app. This time, make sure that the Show Traffic checkbox is checked. Click Launch Map again to see that traffic data is rendered onto the map. If not, then Bing might not have traffic data for that particular location.

Much more can be done with the Maps app. In fact, the full functionality exposed by the Web version of Bing Maps is also accessible to the Maps app and, as a rule, follows the same parameter name and value format. For more information on how to build a Bing Maps URL, see bit.ly/1MIoJ5K.

More Than Maps

While mapping adds significant value to this app, there are many food-finding apps available in the Windows Store. It would be beneficial to differentiate this app by adding a unique feature: music search. For example, if St. Louis were in the Location textbox, users could search for songs about St. Louis and listen to music about their destination. The app will offer users a chance to search for songs with the name of the location in the title. Protocol activation makes it easy to incorporate searches from the Windows Store into apps.

To accomplish this, add the following code to the event handler for the btnSearchMusic_Click event:

private async void btnSearchMusic_Click(object sender, RoutedEventArgs e)

{

  string uriString = string.Format(

    $"ms-windows-store://

    search/?query={txtLocation.

    Text}&type=Songs");

  Uri uri = new Uri(uriString);

  await Launcher.LaunchUriAsync(uri);

}

Run the app once again, enter a city name in the Location textbox, and click Search Music. The Windows Store app should launch and display a search of songs with the city name in the title. For instance, if a user entered “St. Louis” as the location, the results would look like what’s shown in Figure 6.

Figure 6 Windows Store App Music Section with St. Louis in Titles of Songs

For more information about the parameters that can be passed to the Windows Store app, refer to the documentation on Windows Dev Center at bit.ly/2pPJvaA.

Advanced Launch Features

Thus far, the examples in the FoodFinder app had specific outcomes in mind. I had intended to launch the default Maps app and the Windows Store app. In cases where developers want to customize the launching experience or give the user a choice in which app launches, the Launcher class exposes additional features through the use of the LauncherOptions class.

Choosing an Application to Launch

From time to time, users will be presented an option to pick which app to launch when there are multiple apps registered to handle a specific file extension or protocol. For example, it’s very common for users to have multiple browsers installed on their systems. In fact, Windows 10 comes with Edge and Internet Explorer. Giving users a choice in which application to launch would be ideal in particular use cases. Fortunately, the LauncherOptions class in the Windows.System namespace makes it easy to customize how the Launcher class acts.

In the MainPage.xaml file for the FoodFinder app, add the following XAML in the StackPanel to add a new button to perform Web searches:

<Button Name="btnSearchWeb" Click="btnSearchWeb_Click" Margin="5">Search Web</Button>

Now, add the following event handler code in the MainPage.xaml.cs file:

private async void btnSearchWeb_Click(object sender, RoutedEventArgs e)

{

  string genre = (cbxGenre.SelectedItem as ComboBoxItem).Content.ToString();

  string queryString = Uri.EscapeDataString($"{genre} in {txtLocation.Text}");

  var searchUri = $"https://www.bing.com/search?q={queryString}";

  var uriBing = new Uri(searchUri);

  var promptOptions = new Windows.System.LauncherOptions();

  promptOptions.DisplayApplicationPicker = true;

  var success = await Windows.System.Launcher.LaunchUriAsync(uriBing, promptOptions);

}

Just as before, this code constructs a URI based on the choice in the combo box and value entered into the textbox. The addition of the LauncherOptions class and setting the DisplayApplicationPicker property to true will trigger a prompt similar to Figure 7. Run the app now, enter some values and click Search Web to see the Application Picker Prompt.

Figure 7 Application Picker Prompt

By default, the DisplayApplicationPicker is set to false, which launches the default browser on the system.

Confirming Launch

It’s important to point out that, in certain situations, Windows will display a prompt to confirm if the user actually wishes to switch apps, as shown in Figure 8. However, UWP developers cannot suppress this dialog. This is an important security precaution to prevent users from running malicious code.

Figure 8 Prompt Confirming Desire to Switch Apps

There might be times when it’s advantageous to confirm with the user that the app intends to switch apps. For these cases, set the TreatAsUntrusted property to “true.”

Remove the line where the Display­ApplicationPicker property is set to true and add this line to the btnSearchWeb_Click event handler immediately after the declaration of the promptOptions variable:

promptOptions.TreatAsUntrusted = true;

Run the solution again, enter a value in the Location textbox, and click the Search Web button. You’ll see a prompt prior to the browser launching. If the DisplayApplicationPicker and the TreatAsUnstrusted properties are both set to true, then only the application picker prompt will display. This streamlines the process for the user, who would likely get frustrated at the process of clicking through multiple dialog boxes to perform a task.

The LauncherOptions class exposes much more functionality and provides flexibility for any number of use-case scenarios. You can find out more at bit.ly/2qoW8LN.

Wrapping Up

In this column, I demonstrated how to use protocol activation in UWP apps to leverage the power of other apps available on the user’s device. This lets you add rich features and conveniences without inserting complexity to its code base. The UWP offers great flexibility via the LauncherOptions class, which lets developers customize the UX.

Frank La Vigne is chief evangelist at DataLeader.io, where he helps customers leverage technology in order to create a better world. He is co-host of the DataDriven podcast and blogs regularly at FranksWorld.com. He has a YouTube channel called Frank’s World TV (FranksWorld.TV).

Thanks to the following technical expert for reviewing this article: Jose Luis Manners


About the Author