Sometimes you may find you in a situation when you have an ASP.NET web application and want to deploy it to a desktop PC. For example, for one of my projects I have the following requirements:
- Simple installation on any Windows-based PC. Installation and configuration should not require knowledge of the Web technologies.
- Ability to start, stop and configure the Web application from a custom desktop application.
- The Web application should be accessible for a local user and all the network users.
- In the same time it should be a regular ASP.NET application that can be deployed as a hosted solution.
It is clear that such solution will be composed from 3 main components: Web application, control application (in my case it is based on .NET/WPF), Web server. And the main question is “What should I use as a server?” To satisfy the project’s requirements, the server should have the following characteristics:
- Easily redistributable
- Configurable via API, configuration files or command line
- Should be controllable externally (Start/Stop via API, command line, etc.)
- Network support
CassiniDev
Already having an experience with CassiniDev server as a solution for the integration tests execution, I tried this one first. CassiniDev is an open-source project that includes a standalone Wev server with GUI and a library. The library, CassiniDev4-Lib.dll, contains CassiniDevServer
class – an in-process Web server implementation.
_server = new CassiniDevServer();
_server.StartServer(“\\path\\to\\web\\content”));
Basically, that’s it - with two lines of code you have a server that hosts your ASP.NET application. At first look this is what is required:
- there is no need to install anything – the server is a part of the control application
- CassiniDevServer can be easily configured and controlled
But there are some cavities and probably the main one is performance. CassiniDev handles all the HTTP requests sequentially, in one thread. It is acceptable for testing but is not practical in production.
Another issue that kicks CassiniDev out of completion is an auto-shutdown after 60-seconds of idleness – it simply stops to handle any incoming requests.
IIS Express
IIS Express is a lightweight version of IIS. It runs as a separate process like full version of IIS web server, but this process is executed under the user’s account. IIS Express is a standalone application and can be started/stopped using a command line, unlike service-based full IIS.
Theoretically IIS Express is xcopy-deployable, but EULA states that IIS Express can only be redistributed using an official installer package. That means if you want to use IIS Express, it should be added as a prerequisite to your installer and will be installed as separated product.
IIS Express uses the same configuration mechanism as full IIS. Probably the easiest way to host the site on IIE Express, is to create own applicationhost.config, deploy it on the target system and use it to start the server:
"C:\Program Files\IIS Express\iisexpress.exe" /config:D:\Fileversum\config\applicationhost.config
Even IIS Express is installed into the system it will not be started automatically on the Windows start. You have to do it by yourself by creating some kind of launcher or incorporating this functionality into the control application, to be able to start/stop the server on-demand.
By default IIS Express does not require elevated permissions, but in the same time it default configuration does not support network requests and port 80. You need the administrative privileges to unlock these features. The post by Scott Hanselman describes the required manipulations, but in short you need to do the following:
- Configure applicationhost.config to bind your site with the public IP address.
- Allow incoming connections and add a new Windows Firewall rule using netsh utility.
Note that netsh does not exist in Windows XP and httpcfg should be used instead. That means an additional complexity for the installation script.
UltiDev Web Server Pro
UltiDev Web Server Pro is a successor for UltiDev Cassini Web Server, a freeware redistributable Web server. The product is relatively new, but it is in active development and demonstrates a good stability, performance and a reach feature set.
Like IIS Express, UWS is a standalone out-of-process Web server. It runs as a service, includes GUI frontend but also provides an API and the command line tools. UltiDev Server cannot be privately deployed, you have to install it. Fortunately the server redistributable packages for InstallShield, Advanced Installer and VS bootstrapper are available.
If you prefer to register your site during the installation, UWS provides a command line utility that can be used for this propose. If you need more control under the site’s lifecycle, a .NET-based API exposed from UWS.Configuration.dll library might be an option. Below you can see a sample code demonstrating site registration:
var app = Metabase.GetWebAppEntry(ApplicationGUID, false);
app.VirtualDirectory = "/Fileversum";
app.PhysicalDirectory = “\\path\\to\\web\\content”;
app.ApplicationName = "Fileversum";
app.AppType = ApplicationType.AspNetOrStaticHtml;
app.ListenAddresses.AddRange(new[] { new ListenAddress(80) });
Metabase.RegisterApplication(RuntimeVersion.AspNet_4, true, app);
And un-registration:
Metabase.UnregisterApplication(ApplicationGUID);
Both operations (registration and un-registration) require the administrative rights. So if this code is incorporated into the control application, it must be able to request the elevated partitions.
As soon as the site is registered, it will be available for the local and the network users. No additional actions are required to start the server or site after Windows reboot.
Additionally, to simplify the site deployment, UWS supports auto detection of the available ports.