Getting started with a Windows 10 IoT Background Application on the Raspberry Pi 3.

“I’m pushing play. I mean it. If we don’t start soon, George Lucas is going to change it again.” – Howard Joel Wolowitz. 

I’ll be publishing a series later covering the use of a Raspberry Pi 3 with Windows IoT Core as a remote speech operated sensor for my home automation system. Before we get to that however, I will be talking through some of the basic functions you might need when developing a background application on the Raspberry Pi 3. The background application is a Universal Windows Platform application – theoretically an application that could be easily ported between an Xbox One, a Windows Phone, a Windows IoT device and a Windows desktop. The application can be configured to start with the Windows 10 IoT operating system, and run in a headless mode (without keyboard, mouse, monitor).

I’d recommend using Visual Studio 2015 (SP1), and the latest build of Windows IoT Core. Create a new project, and select the Background Application (IoT) project template from the Windows IoT core section.

Background App Project

Let’s quickly add some code, and then we can look at the options.

using System.Diagnostics;
using Windows.ApplicationModel.Background;

namespace BackgroundApplication1
{
    public sealed class StartupTask : IBackgroundTask
    {
		private BackgroundTaskDeferral _deferal;

		public void Run(IBackgroundTaskInstance taskInstance)
        {
			Debug.WriteLine("StartupTask.Run()");

			_deferal = taskInstance.GetDeferral();
			taskInstance.Canceled += TaskInstance_Canceled;
		}

		private void TaskInstance_Canceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
		{
			Debug.WriteLine("StartupTask.TaskInstance_Canceled() - {0}", reason.ToString());

			_deferal.Complete();
		}
	}
}

 I’ve added a tiny bit of code to the base template. The Run() method will be called by the system when the application starts, and thanks to the configuration of the BackgroundTaskDeferral object, the system will call the TaskInsance_Canceled() method when the application is requested to close. Any application logic should typically be asynchronously started from the Run() method.

Before going into any more code, let’s look at some of the other settings you’ll need to play around with. Firstly, the package manifest, which you can find in solution explorer.

Pacakge Manifest

When your application is ready for deployment, it will be placed inside a deployable package. This package will have its own name, description, execution configuration – and quite importantly, capabilities. The capabilities section is where you can declare which system functions your application needs permission to perform. For example, if your application needs to access the system microphone – you will need to declare that capability. For the purpose of a Windows 10 IoT application – we need to be sure to include the capabilities we need, but you won’t need to approve their use from the end device – like you might have to do with a phone.

We also need to configure Visual Studio to allow you to deploy and debug the application on the Raspberry Pi 3 (or Pi 2 of course). This can be configured on the project properties, debug tab. You will be able to browse for Windows 10 IoT devices on your network.

Debug

With that, you should be able to start debugging the application live on the device. You can start debugging as you would with a normal application (F5 or the menu). You should see the output of the Run() method’s call of Debug.WriteLine(). If you then connect to the web interface of the IoT core device and navigate to the running applications page – not only will you be able to see the running application but you will also be able to shut the application down. Once you shut the application down, you will see the TaskInsance_Canceled() method’s call of Debug.WriteLine(), and then the debugger will stop. Easy.

Let’s add a quick logging function, and then we should be complete.

If you’ve not spent a lot of time with the async and await asynchronous programming commands in .NET, I’d recommend first reading a guide on that topic.

using System;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using Windows.Storage;

namespace BackgroundApplication1
{
	internal class Logging
	{
		public static async Task WriteSystemLog(string strFormat, params string[] strParams)
		{
			await WriteLog("System", strFormat, strParams);
		}

		public static async Task WriteDebugLog(string strFormat, params string[] strParams)
		{
			await WriteLog("Debug", strFormat, strParams);
		}

		private static async Task WriteLog(string strLog, string strFormat, params string[] strParams)
		{
			DateTime dtNow;
			string strLogFile;
			string strLogData;
			StorageFolder storageFolder;
			StorageFile storageFile;

			try
			{
				dtNow = DateTime.Now;
				strLogFile = string.Format("{0}_{1}.Log", strLog, dtNow.ToString("yyyyMMdd"));
				strLogData = DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss.ff ") + string.Format(strFormat, strParams);

				Debug.WriteLine(strLogData);

				// Apply Asynchronous Lock here
				{
					storageFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
					storageFile = await storageFolder.CreateFileAsync(strLogFile, CreationCollisionOption.OpenIfExists);

					using (StreamWriter writer = new StreamWriter(await storageFile.OpenStreamForWriteAsync()))
					{
						writer.BaseStream.Seek(0, SeekOrigin.End);
						await writer.WriteLineAsync(strLogData);
						writer.Flush();
					}
				}
			}
			catch (Exception eException)
			{
				Debug.WriteLine(string.Format("Error: WriteSystemLog() {0}", eException.Message));
			}
		}
	}
}

Here we’ve created a reusable logging function that will log to the package’s local storage area on the device. You’ll be able to find those files in Windows Explorer, connecting to the c$ share of the IoT file system. The path you’re looking for is:

\\minwinpc\c$\Data\Users\DefaultAccount\AppData\Local\Packages\<YourApplicationPackageName>\LocalState

Whilst I’d be trying not to store data on the device unnecessarily – due to the instability of some applications running on the IoT device, I find it handy having logging data kept that I can use for later troubleshooting.

In order to use these asynchronous logging functions, we will need to add the async and await keywords to the original class.

using Windows.ApplicationModel.Background;

namespace BackgroundApplication1
{
    public sealed class StartupTask : IBackgroundTask
    {
		private BackgroundTaskDeferral _deferal;

		public async void Run(IBackgroundTaskInstance taskInstance)
        {
			await Logging.WriteDebugLog("StartupTask.Run()");

			_deferal = taskInstance.GetDeferral();
			taskInstance.Canceled += TaskInstance_Canceled;
		}

		private async void TaskInstance_Canceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
		{
			await Logging.WriteDebugLog("StartupTask.TaskInstance_Canceled() - {0}", reason.ToString());

			_deferal.Complete();
		}		
	}
}

 You’ll notice in the logging function – we will need to use an asynchronous lock to protect access to the log file. This is due to the likelihood of multiple parallel methods attempting to call the asynchronous logging method at the same time, resulting in multiple attempts to write to the same file. There is a good article here on the use of asynchronous locks.

There’s only one last thing to do – and that’s ensure the application starts automatically on device boot. For this, you’ll need to do some work in PowerShell. You’ll need to enter a remote PowerShell session to your Windows 10 IoT device. From there, you’ll be able to use the setbootoption and iotstartup commands to instruct the device to start your application package.

net start winrm

Set-Item WSMan:\localhost\Client\TrustedHosts -Value minwinpc

Enter-PSSession -ComputerName minwinpc -Credential Administrator 

setbootoption headless

iotstartup list

iotstartup add headless YourPackageNameHere

shutdown /r /t 0

There you have it, the basics needed to get an IoT application started automatically on your device, with a basic logging function.

~ Mike

6 thoughts on “Getting started with a Windows 10 IoT Background Application on the Raspberry Pi 3.

  1. Thanks for a good article!

    Have you ever run into a situation where the published app to the Pi does not want top start?
    I have been struggling for a while now, trying to figure out why my app will not start. I attached VS debugger to the device and I receive the following exception.

    Could not load file or assembly ‘System.Threading, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’ or one of its dependencies. The located assembly’s manifest definition does not match the assembly reference.

    I have been trying to figure out how .net core works on windows 10 core iot and also how the app packages work, to better understand why I am seeing this message. Using traditional knowledge of Windows and the .net framework I know that the .net framework resides on the host computer running a .net application. I also know that this message “Could not load file or assembly” means the app is unable to load the necessary assembly. What I am trying to figure out is should System.Threading already be on the pi when windows IOT core was installed, or does System.Threading get packaged into the app package and then deployed to the device? Or is it a version issue?

    Apologies for all the Q’s, I figured I’d ask someone who had more success deploying and running a app to see what you would recommend.

    Kind Regards
    Brendon

    1. Howdy, I’ve not seen that issue. Things to try though:
      1. Use the latest version of Visual Studio 2015 (Update 2).
      2. Are you trying to add references to .NET 4 libraries? As a UWP application – you should more or less just have a reference to the UWP framework – not the .NET 4 libraries.

      Let me know how you go.

      1. Hi Mike,

        So I have my background task working. The culprit was ReaderWriterLockSlim that I was using in my background application. I assumed that UWP would automatically allow the use of .net core assemblies. Do you perhaps know of an equivalent?

        I still need to learn a thing or two on how the new Microsoft landscape is supposed to come together from the desktop OS to the IOT device and which frameworks are supported by which OS/device etc….

        Kind Regards
        Brendon Greyling

  2. Howdy, no sadly – it really is quite different in UWP – not all of that base functionality exists. However…. I actually found I had a bit more flexibility in a UWP Class Library. I actually moved quite a bit of functionality into that. To your specific point though, I was using an AsyncLock. There’s a link half way through this article to a site that talks about implementing asynchronous locks – which I use for controlling access to the log file.

    Good news about having the app actually working though – it’s a minor miracle just getting the basic app deployed and running, before starting to worry about functionality! 🙂

    Mike

    1. Hehe, I hear you!

      Thanks again for the help. Now I can start having some real fun and I’ll check out the link to implementing AsyncLock as an alternative to ReaderWriterSlimLock.

      All the best!

      Kind Regards
      Brendon Greyling

  3. Thank you thank you thank you!
    I was getting frustrated since the logging frameworks NLog and log4net do not seem to want to play nice under Win IoT. Your solution was just plain stupid simple and I was able to quickly setup a logging system for just exactly what we needed. Again thank you!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s