Microsoft Machine Learning in the Universal Windows Platform

In March, 2019, it was mentioned in a Microsoft machine learning ML.Net presentation by Microsoft Principal Program Manager Cesar De la Torre Llorente that the preliminary ML.Net SDK, version 0.11, did not yet support the Universal Windows Platform (UWP) because of UWP limitations on reflection. I decided to test this proposition by implementing the multiclassification .Net Iris console tutorial, which uses the famous Anderson Iris Flower Data Set, in a UWP Desktop Bridge pure Win32 “fullTrustProcess” and only rely on UWP for the user interface.

Because the original tutorial was implemented as a console program, I decided a Win32 console process could easily be converted into a Win32 AppService, started from the main UWP program, communicating with UWP over an AppServiceConnection. 

When originally built using ML.Net version 0.11, the UWP sample did run but always provided blank predictions, regardless of the input used. However, when the sample was upgraded to the current release version, ML.Net 1.0, and the MLDotNetWin32 code updated to the current API, the application did start to provide predictions. However, because ML.Net does not yet officially support UWP, the sample only runs in Debug mode from the Visual Studio debugger. Attempts to start the UWP program from the Start menu results in the application terminating unexpectedly when Windows loads the Win32 AppService process.

These problems aside, this sample does run under Visual Studio 2017 and 2019 in Debug mode and can provide insights into development of ML.Net applications under UWP when that environment becomes officially supported by Microsoft.

The packaging architecture is shown below:

MLDotNetUWP Packaging Architecture

In Visual Studio 2019, the solution looks like this:

MLDotNetUWP Visual Studio Solution

The Packaging project is used for publishing and contains references to the UWP and Win32 projects. The resulting UWP application looks like this:

MLDotNetUWP application with prediction in Status area

As you can see, we have already clicked the BuildModel button and made a prediction with the Predict button. The values entered are the default values from the Microsoft ML.Net Iris tutorial, and the output is in the green Status area below. These are the same values as those predicted by the Microsoft console application tutorial.

ML.Net is a promising addition to the Microsoft family of machine learning solutions and when it does eventually support the Universal Windows Platform, this sample may provide a point of departure for your own applications.

To look at this tutorial in-depth, you may find it at my GitHub repository at https://www.github.com/PaulaScholz/MLDotNetUWP. It may also be found linked from the Microsoft ML.Net Community Samples page at https://github.com/dotnet/machinelearning-samples/blob/master/docs/COMMUNITY-SAMPLES.md

Good luck, and happy machine learning!

The Apple Push Notification Service

Apple Push Notification Logo

Push notifications are a powerful tool for communicating with users and can spur them to action.  Sports scores, news items, stock prices and shopping bargains are all common uses of these notifications, which on devices look and work like SMS text messages, but on the iPhone only reach users that have installed your app and have opted in to receive them.

On iOS, push notifications are powered by the Apple Push Notification Service (APNS) and allow you to interact with your users even when they aren’t using your app.  In the last few years, iOS application development has shifted from Objective-C to the Swift language, but many applications are still written in Objective-C to take advantage of legacy code and frameworks. But there are few comprehensive tutorials that show how to implement APNS in a modern Objective-C iOS application written with the latest version of Xcode.

In my latest tutorial, I show how to provision, code and test APNS notifications in Objective-C for iOS 12 using Xcode 10 on MacOS Mohave.  Provisioning the APNS is more complex than the code itself, and I show step by step how to navigate this process.  You may find this tutorial at my GitHub repository at https://github.com/PaulaScholz/ApnsSample.

PreInstalledConfigTask, UpdateTask, SessionConnected task, and Protocol launching of Universal Windows Platform applications

PreInstallConfigTask Sample Logo

Original Equipment Manufacturers (OEMs) and enterprises that create their own operating system images for deployment sometimes need to ship pre-installed applications. Preinstall and update tasks provide the mechanisms that allow these Universal Windows Platform (UWP) tasks to run in the background before the app is installed or when it is updated. 

In my latest sample, I demonstrate the use of the deployment PreInstallConfigTask task to automatically run a target UWP application on first startup. The act of running the target application can register any regular BackgroundTasks and I show how to do this.

I also show how to use the UpdateTask to display a Toast notification when the application’s build number is incremented during a software update. You may augment this task with your own operations if needed.

I show how to register a “Protocol” in the application manifest so the application can be started by referencing a URI, either from a browser or another application. You can use this capability to support your auto-run operations.

Finally, I use the SessionConnected task, a normal UWP BackgroundTask fired by a SystemEvent trigger, to auto-run the target UWP application after user login by using the Protocol. In the sample, this task also shows a Toast notification to the user.

PreInstalledConfigTask Solution Stack

The PreInstalledConfigTask project and documentation may be found at my GitHub repository at https://github.com/PaulaScholz/PreInstalledConfigTaskSample

Paula’s FlipPdfViewerControl Project

Paula’s FlipPdfViewerControl inside sample host program

Recently, for a Universal Windows Platform (UWP) C# project, I was asked to implement Adobe PDF viewing capability for small PDF files that would be attached as part of a user record. The requirements did not involve creating any PDF files, or filling out PDF Forms, or anything more complicated than viewing the PDF file pages in the user interface, and then printing them on demand. Also, in the same display space, we might need to display individual image files that might be attached to the record, like pictures of people or buildings, or scans of other documents that were not PDF files.

As always, I searched the Web for projects that might implement some aspects of the requirements that I could use as springboard for development. There were lots of commercial PDF viewers out there, but almost all were part of some overall control toolkit that cost a lot of money and came with limiting license restrictions, none of which we could live with.

While there were a few open-source projects, there really wasn’t anything I could use without considerable modification, and so I decided to roll my own. The result of these efforts I now make available to the developer community at large as the FlipPdfViewerControl. The article and documentation is at my GitHub.io site, and the complete source code is available on my personal GitHub repository.

Semantic Zoom for Windows 10

Software applications often have grouped data, that is, data that may be organized into groups by date or name or category, like the records in a contact list that are viewed by last name, or the pictures in a photo collection listed by date. Sometimes we might want to zoom in on that data, looking at details on demand, modifying the selection and structure of the data to be displayed.

On the Universal Windows Platform (UWP) for Windows 10, a common way this is done by a mechanism called Semantic Zoom, which is not a graphical zoom, but is instead a view transformation from an overall grouped view into a section of data that represents a group of interest. Working on the structure of data by evaluating its meaning adjusts the contents of our view into detail we desire.

One example of this is the contacts list on a phone, where the overall list may be displayed as an index of letters representing the last names of our contacts. With the UWP Semantic Zoom control, this is known as the ZoomedOut view. When a letter is pressed, the view changes to the ZoomedIn view, bringing the details represented by that letter into visual focus. This is a very powerful way of visually navigating through a large set of data, with the index providing a shortcut to the group we want to see.

Recently, I was asked to provide exactly such an index for a data set in a Windows 10 application, and one of the requirements was to show empty groups, that is, groups represented by a letter that had no members, just like what you might see on a phone. 

There are a few articles on the web about the Semantic Zoom control, and several sample projects, but none of these went into enough depth to show how one would make an index (ZoomedOutView) with grayed-out un-clickable members, and this was one of the features I was asked to implement. Like all developers, I like to search the web for previous work but didn’t find much on this exact subject, so I decided to write an article and provide a working code sample to help those with a similar problem to solve. 

The result of these efforts I now make available to the developer community at large as my UWP Semantic Zoom Tutorial. The complete source code for Microsoft Visual Studio 2017 is available at my public GitHub repository.

If you’re a Universal Windows Platform developer, and who isn’t, this may prove useful to you. Good luck, and happy programming!

Using the Registry from a Universal Windows Platform application

RegistryUWP

Many operations in Windows require access to the Registry, either to read key values or to write to them. However, because of “sandbox” restrictions that make apps secure in the Universal Windows Platform (UWP) for Windows 10, access to the Registry is forbidden.

Microsoft recognizes that some UWP developer scenarios do require access to the Registry and other native Windows resources and has made available a mechanism called Desktop Bridge that brings the power of Win32 to UWP applications. Originally codenamed “Project Centennial”, Desktop Bridge can also enhance WPF and WinForms apps with UWP controls on Windows 10.

In this RegistryUWP sample project, we use the Windows Desktop Extensions for the Universal Windows Platform to launch a “runFullTrust” Win32 application that acts as a Background process to read from the Registry. This Win32 background process is contained within the same Appx package as the UWP program and shares the same lifetime, that is, when the UWP program ends, its companion Win32 background process also ends. This Win32 process has access to all the powerful features of Windows, including those forbidden to normal UWP applications.

However, writing to the Registry requires Administrator privilege, so when a write operation is desired, the Win32 background process launches a separate elevated process with that privilege to execute those operations. This action requires Administrator approval, so when the elevation request is made by the Win32 background process, Windows launches an elevation dialog for the user to provide these Administrator credentials. The elevated process launches, performs the required write operations, and then exits immediately, returning control to the background Win32 “runFullTrust” process, which then reports its status to the UWP application over the Desktop Bridge AppServiceConnection.

These powerful techniques also work with Windows S-Mode (Secure mode) systems, a version of Windows that can only run pre-installed applications or applications acquired from the Windows Store. Because these “runFullTrust” and “allowElevated” techniques have such power, applications that use them receive special scrutiny when submitted for distribution by the Windows Store and require special approval.

The RegistryUWP project and documentation may be found at my GitHub repository at https://github.com/PaulaScholz/RegistryUWP