Category Archives: Universal Windows Platform

GetFilesAsync is not returning all the files in the “My Documents” folder

The following code should return a list of all files in the “My Documents” folder:

    var files = await KnownFolders.DocumentsLibrary.GetFilesAsync();
    List<FileInformation> filesList = new List<FileInformation>();
    
    System.Diagnostics.Debug.WriteLine($"File count: {files.Count()}");

The returned count from this code is (in my case) 11. However, excluding folders, there are 61 files in that directory for me. When I iterate through the collection, it does indeed find 11.

After scratching my head for a while, I finally realised that the answer to my question was my own blog post. It only lists the allowed types.

Reading and Opening a Zip File in a UWP

Some years ago, I had an idea for an application, and the functionality of that application involved extracting the contents of a zip file. I spent a while trying to work out how to do this in VB6 programmatically, and finally got bored, and my app never happened (not that there was such a thing as an app at the time).

Recently, I thought that I might re-visit my idea. Things have moved on since VB6, and this is how to work with zip files in 2016.

The following code will allow you to access the files inside an archive:

 
public async Task GetZipFileInformation(Stream stream)
{
    System.IO.Compression.ZipArchive zip = new System.IO.Compression.ZipArchive(stream);
 
    var firstFile = zip.Entries.FirstOrDefault();
    if (firstFile != null)
    {
    …

Generally speaking, this is much easier that trying to automate PKZIP, or whatever we used to use back in 2002!

UWP Accessing Documents Library

Accessing the documents library from a UWP app is frowned upon by Microsoft; however, it is possible. Here is some code that will access the library:

var files = await KnownFolders.DocumentsLibrary.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByName);
 
foreach (var f in files)
{
    BasicProperties props = await f.GetBasicPropertiesAsync();

This will access the library and get the properties for each file. However, just running it will fail with this error:

uwpdoclib1

So, you’ll probably get this error and, like me (and not for the first time), go looking for it here:

uwpdoc2

Of course, you won’t find it (because it’s not there), and then you’ll turn to Google. If that brought you here then you’re next step is to open the manifest file directly:

…
  <Capabilities>
    <uap:Capability Name="documentsLibrary" />
  </Capabilities>
</Package>

If there are already Capabilities then just add the line:

    <uap:Capability Name="documentsLibrary" />

Note: you need the uap prefix.

And, that’s not all. Next you need to tell it which documents it can access:

      <Extensions>
        <uap:Extension Category="windows.fileTypeAssociation">
          <uap:FileTypeAssociation Name=".txt">
            <uap:DisplayName>Text</uap:DisplayName>
            <uap:SupportedFileTypes>
              <uap:FileType>.jpg</uap:FileType>
              <uap:FileType>.txt</uap:FileType>
              <uap:FileType>.gif</uap:FileType>
              <uap:FileType>.doc</uap:FileType>
              <uap:FileType>.xls</uap:FileType>
            </uap:SupportedFileTypes>
          </uap:FileTypeAssociation>
        </uap:Extension>
      </Extensions>
    </Application>
  </Applications>
  <Capabilities>
    <uap:Capability Name="documentsLibrary" />
  </Capabilities>
</Package>

And that’s it. I can understand why they have all these restrictions, but they can be frustrating for programmers.

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.

XAML Translations based on the display size in UWP

Having recently released my latest app into the store, I noticed that some of the buttons didn’t fit well on the phone version. I’d already come across translations for the HTML/WinJS version of Windows 8 apps, but not the XAML version, and not Windows 10 UWP.

You can do this in Expression Blend

First, double click the view file:

transuwp1

In the States window, you’ll then have the ability to create a new VisualStateGroup:

transuwp2

Create the required states; here’s mine:

transuwp3

If you click the lightning bolt to the side of the group, you should get the following:

transuwp4

If you create an adaptive trigger as above, you’ll be able to set the minimum width or height for the change. I’ve set the minimum width for desktop form factor to 500.

Back to code

What that produces for you (remember that you can alt-tab between Blend and VS and it should deal with the changes relatively gracefully) is a piece of code along the lines of this, within the XAML view:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <VisualStateManager.VisualStateGroups>

            <VisualStateGroup x:Name="VisualStateGroup">

                <VisualState x:Name="Normal">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="500"/>
                    </VisualState.StateTriggers>
                </VisualState>

                <VisualState x:Name="Mobile">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="320"/>
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="tgPlay.(Grid.Column)" Value="0"/>
                        <Setter Target="tgPlay.(Grid.Row)" Value="1"/>
                        <Setter Target="btnCommandCreateVideo.(Grid.Row)" Value="1"/>
                        <Setter Target="btnCommandCreateVideo.(Grid.Column)" Value="1"/>
                        <Setter Target="btnCommandClear.(Grid.Row)" Value="1"/>
                        <Setter Target="btnCommandClear.(Grid.Column)" Value="2"/>
                        <Setter Target="numericUpDown.(Grid.Column)" Value="0"/>
                        <Setter Target="numericUpDown.(Grid.Row)" Value="1"/>
                        <Setter Target="numericUpDown.(Grid.ColumnSpan)" Value="3"/>
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

There’s a number of points here – the first is that you need to name your controls; that’s how they are referenced. If you use Blend and you don’t do this then blend will give them a name; for example, I didn’t give “numericUpDown” a name. If I had another control of the same type then it would just number them.

The second point is the adaptive trigger. 500 and 320 seem to be the generally accepted divisions between desktop and narrow form factor. This approach worked for my specific requirement, although what Blend produces does require some re-work, otherwise it just ends up as a mess.

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