All Articles

Running a desktop app with AngularJS served from a Windows Service with Katana (OWIN)

Nowadays, when developing desktop applications for Windows, we have many options when choosing the .Net technology to use:

  • Windows Prsentation Foundation (WPF) - in my opinion, this is the most consensus choide
  • Windows Forms
  • Silverlight

If the target is Windows 8 we can add even more choices to the pile, for example using HTML5 and Javascript, due the support of the new WinRT architecture.

Recently I had to analyze a scenario where a windows service should be developed, which would be responsible to run some kind of scheduled tasks - polling a SaaS service on the public internet, and integrate some data with on-premises systems. Additionally, a graphical tool should also be developed, to allow to configure some aspects of the windows service (instead of editing configuration files by hand).

For the UI tool, my first approach was to choose a WPF application. But I have no experience at all with WPF, and as a developer I am more comfortable with the web stack development, which means that on the client side I would like to use Html5 and Javascript, and the UI tool would be running on the browser.

Since I'm in love with AngularJS, my wish was to develop the tool using AngularJS. But I don't want to complicate the installation process, requiring my tool to be hosted in Internet Information Service (IIS). So, what I really want is to install my window service, which besides the integration logic, should also host my AngularJS application.

Well, in fact, what I really need is to have some kind of embedded web server that supports:

  • Static files - (html, images, css and javascript files)
  • AspNet Web Api - I want to use WebApi to return the data to the graphical tool

With this goal in mind, it's time to meet OWIN (Open web Interface for .Net) specification and the Katana Project.

From the OWIN site

OWIN defines a standard interface between .NET web servers and web applications. The goal of the OWIN interface is to decouple server and application, encourage the development of simple modules for .NET web development, and, by being an open standard, stimulate the open source ecosystem of .NET web development tools.

So, basically, OWIN is a spec which allows components to be reused on different web servers.

The Katana Project is a collection of projects to support OWIN with various Microsoft components. It is also a command line application for running self-host servers. To have a great overview of the Katana project read this post.

Ok, stop theory, and show me the how can I use Katana to embed a small web server on my windows service. which allows me to build an AngularJS app. Here we go!

First, let's create a new Visual Studio project, choosing the type Windows Service

image

 

Next, let's make some modifications to the project to allow us to test without having to install the windows service:

  • Change the project type to Console Application (Project Properties)

image

  • Change the Start and Stop methods of the windows service to allow calls from a console app

image

  • Add a conditional compilation statement #if to allow to run in Debug as a console application

image

Now let's start to embed our web server. We will need some nuget packages

The first NuGet we will need it's the Microsoft.Owin.Hosting, which allow us to have a basci OWIN hosting in our application

image

Notice that the package is a pre-release version, so we should change the option in the drop down "Stable Only" to "Include Prerelease". To create our web application host, we just need to modify out internal start and call the method WebApplication.Start, indating the listen url as parameter (http://localhost:12345).

image

The Start method is a generic method, where we have to tell what is the class responsible to do the initial startup, which in our case it is the WebStartup class. By convention, the method to be called it is named Configuration, receiving the application builder object as an argument

image

Let's try to run our application, hitting F5, to see what happens

image

We are getting an exception, telling us that the HTTP Listener is not found.

Could not load file or assembly 'Microsoft.Owin.Host.HttpListener' or one of its dependencies. The system cannot find the file specified.

 

Until now, what we did was just adding the hosting capabilies to our application. We need to specify the OWIN component that should listen for and serve HTTP requests. Let's add the Microsoft.Owin.Host.HttpListener NuGet, which is the OWIN component that uses the Microsoft Windows HTTP protocol stack (http.sys)

image

Let's hit F5 again and see what happens

image

As you can see nothing happens, and the exception disapears. However I want to have a quick way to check if the hosting is correct. To do this, we will add another NuGet Microsoft.Owin.Diagnostics, which will allows to have a quick diagnostics

image

Next, we need to tell to our web application to use the diagnostics capabilities, calling the method UseTestPage() during the configuration phase

image

Let's hit F5 again, and open a browser and type our url on the address bar

 

image

Cool! Now we have an http listener which serves always this simple test page, greeting "Welcome to Katana". Now we need to add another NugGt, Microsoft.Owin.StaticFiles, which will allow us to serve our static files (Html, CSS, Javascript files, etc.). For some reason, this nuget is not being returned in the search result when using the window "Manage NuGet Package". So, we will have to use the Package Manager Console and use the command

Install-Package Microsoft.Owin.StaticFiles -Version 0.20-alpha-20220-88 -Pre

image

 

Now we need to configure our static files component to tell the path where the static files are. In my case I choose to create a folder webdir to be the static files container, and it will be located in the same directory of the executing assembly

image

Let's add an Index.html file to webdir folder and try to navigate to this page in the browser (do not forget to mark this file to be added to the output directory)

image

 

image

Hit F5 and browse to http://localhost:12345

image

Very good. Now we can serve static files. Half of our problem is solved, since an AngularJS application it's just a bunch of Html, javascript, CSS, and imagesfiles.

But if you remember, we need also to use WebApi, which is the way to return some data to the app. Let's add another NuGet, Microsoft.AspNet.WebApi.Owin, which will allow us to host WebApi controllers and provide a REST api on our application.

image

Now we need to configure the WebApi, telling the route pattern to use.

image

Basically we configured to use the route /api/{controller} tou our WebApi controllers. Let's add a simple HomeController with the Get method, returning a simple string.

image

Let's Hit F5 and browse to the url http://localhost:12345/api/home

image

The WebApi content-negotiation resulted in a json fle. Let's click Open to see the content

image

Bingo. Our application now handles WebApi.

Finally, to install this as a windows service, we just need to add a project installer

image

Compile in release mode, install the windows service (using installutil.exe) and you are ready to add your AngularJS application, which will be served by the windows service process, without the need of Internet Information Service (IIS). With this, now I can consider to build my configuration tool (to run on desktop) using AngularJS and WebApi.

You can download the full code in my github account.

Published Jun 4, 2013

Cloud Solutions and Software Engineer. Married and father of two sons. Obsessed to be a continuous learner.