Running a Console App on the Raspberry Pi for the (Windows) .NET Developer

As a .NET developer I've always been curious about the world of Mono, but have never really taken the opportunity to see what it was capable of. Lately, a little ARM-based computer called the Raspberry Pi has been drawing a lot of attention because it is inexpensive ($35 for the Model B), and has many capabilities due to the various inputs and outputs that it provides. My first project with my newly acquired Raspberry Pi is to port the Bespoke Dynamic DNS Updater to Linux/Mono. What I have found is that really all of the hard work is in configuring the Linux environment and Mono, and that porting this particular console application is incredibly easy to do otherwise.

Picking an OS

Supported Operating Systems for the Raspberry Pi can be found on the Raspberry Pi Downloads Page. The recommended OS for getting started with the Raspberry Pi is Raspbian "wheezy" (a Debian-based linux distro), however this is a hard-float (hardware optimized floating point calculation) OS, and the stable build of Mono at the time of writing has a number of issues with this Linux distribution. More details about the Raspbian Port can be found here:

Therefore, I installed Soft-float Debian "wheezy" on my Raspberry Pi to get the Mono support that I needed. Instructions and links for downloading the OS can be found on the Raspberry Pi Downloads Page. Once the stable Mono Release (v. 3) is available for Raspbian, I will be moving over to hard float Raspbian to realize performance benefits (not really needed for the Bespoke Dynamic DNS Updater, but certainly useful in other situations). Some more discussion about the availability of the Hard Float Mono port can be found here:

More info about hard float vs soft float OS versions for the Raspberry Pi and performance consideration can be found here:

Installing Remote Desktop

Since I develop .NET software in the Windows environment, I wanted to ease into the world of the Raspberry Pi using tools that I am already familiar with. I figured it would be nice to use the existing Windows Remote Desktop client to connect to the RaspPi rather than having to install a new client. In order to install a RDP Server on the Raspberry Pi, issue the following commands from the command line:

sudo apt-get update

This updates the Debian package manager to the latest version, to ensure that when you download software packages, you are getting the most recent versions.

sudo apt-get install xrdp

This installs the Remote Desktop Server on the Pi.

sudo ip addr show

This is how you determine the IP Address for the PI for initiating a connection from your Windows computer. You use this, along with the credentials for your Raspberry PI to connect. The default credentials are:

Username: pi Password: raspberry

Installing Mono

Mono is not installed by default after installing Debian, so it will need to be installed using apt-get. From the command line (which can be accessed from LXTerminal once connected via Remote Desktop), there are two options:

1) The one-liner, give-me-everything approach (mono-complete: This components such as the Mono Runtime, Base Class Libraries, Compiler, Development Tools and more. This package will take a long time to download/install, and will install components that you may not ever need, but on the plus side, there may be dependencies in this package that you may have to otherwise hunt down to get your application installed. The command to install this is:

sudo apt-get install mono-complete

2) In order to install the Bespoke Dynamic DNS Updater Console App, I found that was also able to get things running by installing just the Mono runtime and Base Class Libraries. The commands to install these packages are:

sudo apt-get install mono-runtime
sudo apt-get install libmono-cil-dev

Porting the Console Application

I had originally expected that I would have to load up the MonoDevelop IDE or configure Visual Studio to target the Mono Framework. Not so. From the Mono FAQ: Yes, Mono can run binaries produced by Visual Studio, there is no need to recompile.

I simply compiled the application using Visual Studio, and copied the output files from the "bin" folder onto a USB drive which i connected directly to the Raspberry Pi. For this particular application I successfully ran the the console app when targeting x86, x64 and AnyCPU for the Platform target, though I think that the best practice would be to target AnyCPU.

Running the Bespoke Dynamic DNS Updater

The Bespoke Dynamic DNS Updater relies on an HTTPS connection for the majority of the services that it supports. By default Mono does not include any default trusted certificates in the certificate store when it is initially installed, so the Bespoke Dynamic DNS updater receives an "Invalid certificate received from server" message when running.

The easiest way to install some default trusted root certificates is to use the mozroots tool, which downloads certificates that Mozilla has identified as trusted root certificates, and installs them into the certificate store. The mozroots tool is included in the mono-devel package. If you opted to install mono-complete, then you will already have this tool, otherwise run this command to install the mono-devel package:

sudo apt-get install mono-devel

Once that package is installed you can install the Mozilla root certificates using this command:

sudo mozroots --import --ask-remove --machine

More information about Mono security and certificate considerations can be found on the Mono Project's security page. The next step is to update the config file for the console app with a hostname and credentials for the DNS service that is to be used, instructions can be on the GitHub wiki. The final step is running the updater, keep in mind that linux is case sensitive!

sudo mono Bespoke.DynamicDnsUpdater.ConsoleApp.exe

Final Thoughts

I was pleased to find that the actual porting of the code was accomplished by little more than an xcopy. This is despite running on a different runtime (Mono), different operating system (Linux) and different processor architecture (ARM) than what the application was originally designed for. The time consuming part of the process was identifying which operating system properly supported mono, understanding which Debian Mono packages are required by default, and figuring out how to easily install a trusted set of root certificates, since mono does not ship with any by default. I look forward to seeing hard float support for Mono in Linux on the Raspberry Pi, the wait should not be long now.

Posted by: David Marchelya
Last revised: 19 Jan, 2013 03:22 PM


David Marchelya Bespoke Industries Denver, CO U.S.A
Product of Bespoke Industries