Tag Archives: UWP

Create and Test an MSix Installation

I’ve previously written about the new Msix packaging project here. One thing that I didn’t cover in that post is that, whilst the process described there will allow you to create an Msix package, you will not be able to deploy it on your own machine. In fact, you’ll likely get an error such as this if you try:

App installation failed with error message: The current user has already installed an unpackaged version of this app. A packaged version cannot replace this. The conflicting package is 027b8cb5-10c6-42b7-bd06-828fad8e3dfb and it was published by CN=pcmic.

Because this has run on your machine, there’s a conflict with the installation. Fortunately, removing the installed version is quite easy; first, copy the package name (indicated below):

Launch a copy of powershell (as admin) and enter the following command:

Get-AppxPackage -name [packagename] -AllUsers

In my case, that would be:

Get-AppxPackage -name 027b8cb5-10c6-42b7-bd06-828fad8e3dfb -AllUsers

You’ll then see something similar to the following (copy the PackageFullName):

Now you can remove the package:

Remove-AppxPackage -package [PackageFullName] -AllUsers

In my case:

Remove-AppxPackage -package 027b8cb5-10c6-42b7-bd06-828fad8e3dfb_0.2.5.0_x64__sqbt0zj9e43cj -AllUsers

Unfortunately, you don’t get any indication this has worked, so type the get command again:

Get-AppxPackage -name 027b8cb5-10c6-42b7-bd06-828fad8e3dfb -AllUsers

And you should see that nothing is returned. Now, when you run it, it should be fine:

References

https://developercommunity.visualstudio.com/content/problem/198610/another-user-has-already-installed-an-unpackaged-v.html

UWP using Unity and EF Core and Sqlite

If you intent to use IoC with a UWP application, there are a lot of options. Most of them come with MVVM packages, like MVVM Cross. These are excellent packages – I’ve used MVVM Cross and MVVM Light myself and can highly recommend them.

However, if you didn’t want all that baggage, how would you implement a very simple IoC system in UWP?

In this example, I’m using Unity, however, I believe this will work for any IoC container. I’m also using the IoC container to resolve a View Model – but you don’t need to use View Models (although IMHO, it makes your life so much easier.)

Secondly, I’ll be showing how to use Ef Core with your UWP app. This sounds very trivial, but there’s a bit of fiddling about to get it to work.

Entity Framework Core Set-up

In my project, I’ve separated the data access layer, but you don’t need to do that. Start by creating a data context:

public class MyDbContext : DbContext
{
    public DbSet<Data> MyData { get; set; }
 
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite("Data Source=mydata.db");
    }
}

You’ll need the following packages:

Install-Package Microsoft.EntityFrameworkCore
Install-Package Microsoft.EntityFrameworkCore.Design
Install-Package Microsoft.EntityFrameworkCore.Tools
Install-Package Microsoft.EntityFrameworkCore.Sqlite

You’ll also need to create a console application – why? Because you can’t use any of the EF tools with UWP! If you set your UWP app as the start-up and create your migration, you’ll get this error:

Startup project ‘SendMessage.UWP’ is a Universal Windows Platform app. This version of the Entity Framework Core Package Manager Console Tools doesn’t support this type of project.

Set the console app as startup and add the migration:

Add-Migration "InitialDbCreate"

Don’t worry about updating the DB, we’ll get the app to do that (it just can’t use the tools, but it can perform a migration.)

UWP

From a new, blank, UWP app; in app.xaml.cs:

sealed partial class App : Application
{
    public static IUnityContainer Container { get; set; } = new UnityContainer();
 
    /// <summary>
    /// Initializes the singleton application object.  This is the first line of authored code
    /// executed, and as such is the logical equivalent of main() or WinMain().
    /// </summary>
    public App()
    {
        this.InitializeComponent();
        this.Suspending += OnSuspending;
 
        using (var db = new MyDbContext())
        {
            db.Database.Migrate();
        }
        
        Container.RegisterType<MainViewModel>();
    }

We’re creating a static UnityContainer in App.Xaml.cs. Register the type (in this case a MainViewModel, but it could as easily be an interface).

The next step is resolving the interface. Unfortunately, because of the way that the UWP navigate works, Unity won’t perform constructor injection for us. A little trick around this is to create a parameterless constructor and have that call the injected constructor. It’s not quite constructor injection, but semantically it’s the same thing. Here’s the code from my MainPage.xaml.cs:

public sealed partial class MainPage : Page
{
    public MainPage() : this(App.Container.Resolve<MainViewModel>()) { }
 
    public MainPage(MainViewModel mainViewModel)
    {
        this.InitializeComponent();
 
        this.DataContext = mainViewModel;
    }
}

That’s pretty much it; you can run this, and it’ll migrate the data, and resolve the dependency.

References

https://docs.microsoft.com/en-us/ef/core/get-started/uwp/getting-started

MVVM Cross Upgrade to 4.2.2

Coming back to MVVMCross and trying to create a new project, I found that some of the documentation available for the new version (4.2.2 at the time of writing this) is no longer correct; for example, the ToDo file in the sample projects still looks like this:

The steps to get this Store UI working are:

1. Add a reference to your Core PCL project
2. Change App.Xaml.cs so that it creates a ‘new Setup(RootFrame)’ during its OnLaunched:

protected override void OnLaunched(LaunchActivatedEventArgs args)
{
var rootFrame = Window.Current.Content as Frame;

// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();

if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}

// Place the frame in the current Window
Window.Current.Content = rootFrame;
}

if (rootFrame.Content == null)
{
// When the navigation stack isn’t restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter

var setup = new Setup(rootFrame);
setup.Initialize();

var start = MvvmCross.Core.Mvx.Resolve();
start.Start();
}
// Ensure the current window is active
Window.Current.Activate();
}

3. For Windows 8 – Add a views folder and a view – xaml.cs and .xaml based on BasicPage – this
will add 5 files to the Common folder.
– Change the Common/LayoutAwarePage.cs inheritance to MvvmCross.WindowsStore.Views.MvxStorePage
– Change the Common/LayoutAwarePage.cs – remove the OnNavigatedTo and OnNavigatedFrom handlers
– Add some content for your Xaml – e.g.

5. For Windows 8.1 – Add a views folder and a view based on the BasicPage template
– In the .xaml.cs – remove public NavigationHelper NavigationHelper and all referencing code
– In the .xaml.cs – remove the OnNavigatedTo and OnNavigatedFrom handlers
– Add some content for your Xaml – e.g.

This document was very useful. I was looking specifically at the Babel project in the above sample; this won’t compile under MvvmCross 4.2.2. I’ve listed here everything I needed to do to make it.

Mvx has now been replaced with MvxSimpleIoCContainer.Instance

In App.xaml.cs:

var start = MvxSimpleIoCContainer.Instance.Resolve<IMvxAppStart>();

Is now:

var start = MvxSimpleIoCContainer.Instance.Resolve<IMvxAppStart>();
start.Start();

In App.cs:

        private void InitializeText()
        {
            var builder = new TextProviderBuilder();
            Mvx.RegisterSingleton<IMvxTextProviderBuilder>(builder);
            Mvx.RegisterSingleton<IMvxTextProvider>(builder.TextProvider);
        }

Is now is a separate plug-in by the looks of things:

mvvmcrossupgrade

The new code is:

        private void InitializeText()
        {            
            var builder = new TextProviderBuilder();
            MvxSimpleIoCContainer.Instance.RegisterSingleton<IMvxTextProviderBuilder>(builder);
            MvxSimpleIoCContainer.Instance.RegisterSingleton<IMvxTextProvider>(builder.TextProvider);
        }

Using MSTest DataRow as a Substitute for NUnit TestCase

I used to believe that Nunit’s TestCase test (that is, an ability to define a test and then simply pass it alternate parameters) was denied MSTest users. It appears that this is, at least now, fallacious.

The following article implies that this is a recent change:

Taking the MSTest Framework forward with “MSTest V2”

This particular example is in a UWP application:

        [DataTestMethod]
        [DataRow(1, 2, 3, 6)]
        [DataRow(8, 2, 3, 13)]
        [DataRow(8, 5, 3, 12)]
        public void AddNumbers(int num1, int num2, int num3, int total)
        {
            Assert.AreEqual(num1 + num2 + num3, total);
        }

Will result in a failing test, and:

        [DataTestMethod]
        [DataRow(1, 2, 3, 6)]
        [DataRow(8, 2, 3, 13)]
        [DataRow(8, 5, 3, 16)]
        public void AddNumbers(int num1, int num2, int num3, int total)
        {
            Assert.AreEqual(num1 + num2 + num3, total);
        }

Results in a passing one.

If you want additional information relating to the test, you can use this syntax:

        [DataTestMethod]
        [DataRow(1, 2, 3, 6, DisplayName = "First test")]
        [DataRow(8, 2, 3, 13, DisplayName = "Second test")]
        [DataRow(8, 5, 3, 15, DisplayName = "This will fail")]
        public void AddNumbers(int num1, int num2, int num3, int total)
        {
            Assert.AreEqual(num1 + num2 + num3, total);
        }

Given the constant problems that I have with finding the correct NUnit test adaptor, and trying to work out which are the right libraries, I think, despite coming late to this party, MS might actually drag people back to MSTest with this.

TaskCompletionSource

I’ve had a couple of problems recently, where I’ve had tasks or asynchronous methods and they don’t quote fit into the architecture that I find myself in. I’d come across the TaskCompletionSource before, but hadn’t realised how useful it was. Basically, a TaskCompletionSource allows you to control when a task finishes; and allows you to do so in a synchronous, or asynchronous fashion. What this gives you is precise control over when an awaited task finishes.

UWP

Consider the following code in UWP. Basically, what this does is execute an anonymous function on the UI thread:

await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, async () => 
{
    await MyAyncFunc();
}
System.Diagnostics.Debug.WriteLine("After MyAsyncFunc");

The problem here is that executing an anonymous async function in the above scenario doesn’t work. However, using the TaskCompletionSource, we can bypass that whole conversation:

TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();

await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, async () => 
{
    await MyAyncFunc();
    System.Diagnostics.Debug.WriteLine("After MyAsyncFunc");

    tcs.SetResult(true);
});
await tcs.Task;

Now the function will return when the the TaskCompletionSource.SetResult has been called.

Event based

The second scenario where this is useful is where you are trying to use an event based architecture within an async / await scenario. The following example is a little contrived, but it does illustrate the point:

    class Program
    {
        private static Timer _tmr = new Timer();
        private static TaskCompletionSource<bool> _tcs;

        static void Main(string[] args)
        {
            var tmr = StartTimer();

            Console.WriteLine("Before wait...");
            tmr.Wait();

            Console.WriteLine("After wait...");
        }        

        private static async Task StartTimer()
        {            

            _tmr.Interval = 3000;
            _tmr.Elapsed += _tmr_Elapsed;
            _tmr.Start();

            _tcs = new TaskCompletionSource<bool>();
            await _tcs.Task;
        }

        private static void _tmr_Elapsed(object sender, ElapsedEventArgs e)
        {
            _tcs.SetResult(true);
        }
    }

Potentially, a more real world example of this is when you might want to wrap an API in an async/await.

Control over exactly when a task finishes, and the ability to await async void methods

The final scenario where this can be useful is where you either want to await an `async void` method, or where you have a specific part of a method or process that you want to await.

The following code illustrates how to effectively await an async void method:

    class Program
    {        
        private static TaskCompletionSource<bool> _tcs;

        static void Main(string[] args)
        {
            _tcs = new TaskCompletionSource<bool>();
            BackgroundFunction();

            _tcs.Task.Wait();

            Console.WriteLine("Done");
        }        

        private static async void BackgroundFunction()
        {
            for (int i = 1; i <= 10; i++)
            {
                Console.WriteLine($"Processing: {i}");
                await DoStuff();
            }
            _tcs.SetResult(true);
        }

        private static async Task DoStuff()
        {
            await Task.Delay(500);
            
        }

    }

Finally, here is a parallel for loop:

        static void Main(string[] args)
        {
            Parallel.For(1, 3, (i) =>
            {
                BackgroundFunction();
            });

            Console.WriteLine("Done");
        }        

Imagine that BackgroundFunction is performing a long running task where a specific condition needs to return control. There are obviously combinations of functions in the TPL (WaitAll, WhenAll, WhenAny and WhenAll), however, these rely on the whole task, or a set of tasks, completing. Again, the below example is contrived, but it illustrates the granular control over the task that you have.

        static void Main(string[] args)
        {
            _tcs = new TaskCompletionSource<bool>();

            for (int i = 1; i <= 2; i++)
            {
                BackgroundFunction();
            }

            _tcs.Task.Wait();            

            Console.WriteLine("Done");
        }        

        private static async void BackgroundFunction()
        {
            for (int i = 1; i <= 10; i++)
            {
                Console.WriteLine($"Processing: {i}");
                await DoStuff();

                if (i == 7)
                {
                    _tcs.TrySetResult(true);
                    return;                    
                }
            }            
        }

I will re-iterate again, I realise that in the above example, there are better ways to achieve this, and the example is purely for illustration.

Conclusion

Generally speaking, the simplest and most robust code comes from using the task architecture in the way it was designed: that is, use async / await inside a method that returns a Task. I’m not suggesting in this post that the methods I’ve described should replace that; but there are situations where that might not fit.

Aknowledgements

I used the following posts heavily while writing this:

Awaiting the CoreDispatcher
The Nature of TaskCompletionSource
Real life scenarios for using TaskCompletionSource?
Task Parallelism

Share Content in a UWP App

Sharing has changed slightly between Windows 8 and 10, but broadly speaking, the concept is the same. This article is pretty much where I worked most of this out from; however, there were some small pieces missing for my implementation:

Sharing Video Files

My target here was to share an avi file that I’d just created. My first step was to create a Share Helper (most of what is in here is described in the linked article):

    class ShareHelper
    {
        private IStorageItem _storageItem;

        internal bool Share(IStorageItem storageItem)
        {
            if (storageItem == null)
            {
                return false;
            }

            _storageItem = storageItem;

            DataTransferManager dataTransferManager = DataTransferManager.GetForCurrentView();
            dataTransferManager.DataRequested += DataTransferManager_DataRequested;                                  

            DataTransferManager.ShowShareUI();
            return true;
        }

        private void DataTransferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs args)
        {
            if (_storageItem == null) return;
                        
            DataRequest request = args.Request;                        
            
            List<IStorageItem> storage = new List<IStorageItem>()
            {
                _storageItem
            };
            request.Data.Properties.Title = "Share";
            request.Data.Properties.Description = "Share your movie!";
            request.Data.SetStorageItems(storage);
            
        }
    }

In Detail

The function SetStorageItems accepts an IEnumarable of IStorageItem. In this case I only have one thing to share, so I’ve just created an arbitrary list. The event handling seems a little overly complex for what it is.

Microsoft recommend that you don’t purposely call the ShowShareUI, but there are a number of situations – for example, the share icon in the camera app – that wouldn’t be intuitive any other way (I’m no UX expert, so I’d be happy to be corrected on this). However, the share UI still behaves as though you has swiped in from the right. To be honest, I kind of expected this Windows 8 chrome to be gone for Windows 10, some is clearly still alive and well.

Roaming and Local Settings in UWP

In the new Universal Windows Platform, you can store settings data in many ways. These days, there are multiple cloud options that you can communicate with; alternatively, you can store the settings in the user’s local profile. You can do this locally (that is, the data is stored on the current device against the current user only), or remotely (which means that the data will automatically be shared across all devices where your app is installed for that user). Both of these are stored as KeyValue Pairs.

Local Settings

Local settings are small, local variables. These are accessible even offline. The following code will only work on VS2015 because of the “?.” syntax; however, a null coalesce “??” will work just as well in older versions of VS.

string mySetting = Windows.Storage.ApplicationData.Current.LocalSettings.Values["MySetting"]?.ToString();

To set the setting, the syntax is basically the same:

Windows.Storage.ApplicationData.Current.LocalSettings.Values["MySetting"] = "1";

There is, as far as I’m aware, no limit to the amount of data that can be stored in these settings.

Roaming Settings

Roaming settings are a small, out of the box, solution for transferring settings across Windows devices. They aren’t new, and they are very easy to use; the following will return “MySetting” or null (VS2015+ only):

string mySetting = Windows.Storage.ApplicationData.Current.RoamingSettings.Values["MySetting"]?.ToString();

To set the setting, the syntax is basically the same:

Windows.Storage.ApplicationData.Current.RoamingSettings.Values["MySetting"] = "1";

The amount of data that can be stored here is apparently, around 100K. You can get the exact figure by interrogating the RoamingStorageQuota property:

Int storage = Windows.Storage.ApplicationData.Current.RoamingStorageQuota

Take this limit seriously; this article implies that, should you exceed it, all roaming will be stopped.

It’s also worth bearing in mind that you need to be online to access roaming storage.

In-line Pre-Processor Directives in C#

While following this article on how to add in-app purchases to UWP apps, I came across a little quirk of conditional compilation directives. Initially, I started structuring my code like this:

Windows.ApplicationModel.Store.PurchaseResults result;
#if DEBUG
    result = await Windows.ApplicationModel.Store.CurrentAppSimulator.RequestProductPurchaseAsync(Description);
#else
    result = await Windows.ApplicationModel.Store.CurrentApp.RequestProductPurchaseAsync(Description);
#endif

But then I realised, that the code can be split over multiple lines such that the compile directive can sit halfway through the command; like this:

Windows.ApplicationModel.Store.PurchaseResults result = await
#if DEBUG
    Windows.ApplicationModel.Store.CurrentAppSimulator.RequestProductPurchaseAsync(Description);
#else
    Windows.ApplicationModel.Store.CurrentApp.RequestProductPurchaseAsync(Description);
#endif

The MSDN documentation of this can be found here.

Frame Rate counters on by Default for Windows UWP Emulators

Something that I spotted today (mainly because my app got ‘notes’ during its submission to the store) is the frame rate counter that is on by default for UWP apps. These are the small numbers down the right hand side of the screen:

framerate1

Your app will pass if you submit screenshots with these, but they don’t look good and, as I said, you get ‘Notes’.

To remove them, search you project for this line:

this.DebugSettings.EnableFrameRateCounter = true;

And just comment it out. If you need to see it then you can simply re-enable it when you’ve taken the screenshot.

framerate3

Huzaar!

(the app in question can be found Here

Deleting Files in a Storage Folder Using UWP

Just a little helper method that I used in a recent project to delete files, given a particular name, and excluding a provided list of files:

        internal static async Task DeleteTempFiles(ObservableCollection<StorageFile> exceptionFiles, StorageFolder folder, string fileNameStartsWith)
        {
            var files = (await folder.GetFilesAsync())
                .Where(p => p.DisplayName.StartsWith(fileNameStartsWith)
                && !exceptionFiles.Any(e => e.DisplayName == p.DisplayName));            

            foreach(var file in files)
            {
                await file.DeleteAsync(StorageDeleteOption.Default);                
            }
        }

You can call it like this:

	await FileHelper.DeleteTempFiles(Files, KnownFolders.PicturesLibrary, "_tmpFile");

It will delete all files in the Pictures folder starting with _tmpFile, and exclude anything in the Files collection.