From the outset, one of the goals of the .NET Framework was to make life easier for developers by uniting the various programming models on the Microsoft platform. These included the RAD and forms-based development inherent in Visual Basic, the power and object-orientation of MFC and ATL, and the Web-based programming paradigm of Active Server Pages. The result is a common language runtime that executes and manages code married to a set of class libraries that exploit all aspects of the Win32 API and various system services known together as the .NET Framework.
Because the .NET Framework makes accessing system services uniform across programming languages, it is no surprise that Visual Basic developers can now take advantage of operating system services that were previously the domain of C and C++ developers. One of the most interesting ways in which leveling the playing field is realized is in the ability of VB developers to create Windows (or NT) services.
It was possible to create Windows services in VB 6.0 with the help of a custom control written in C. See Chapter 19 of my book Pure Visual Basic for more information.
I've written extensively in the past on creating Windows services in VB .NET (see Chapter 13 of my book Building Distributed Applications in Visual Basic .NET), so I won't repeat that discussion here. However, in this article I'll review a couple of the important issues to consider when developing and debugging Windows services.
Web Service or Windows Service?
Existing long before the advent of Web services, a Windows service (also referred to as an NT service) is simply a process that runs in the background under the Windows NT/2000/XP operating systems, has no user interface (UI), and is controlled through a set of Win32 APIs and the Windows service controller (also referred to as the Service Control Manager, or SCM). Simply put, the SCM is comprised of the operating system components responsible for configuring and running an executable as a service. These background processes can be started, stopped, paused, and continued through the services console and can run under the context of a specific account. Application servers such as SQL Server and Exchange Server run their core processes as Windows services.
That said, the .NET Framework provides a set of classes in the System.ServiceProcess namespace that provides a managed wrapper for the underlying Win32 APIs and allows developers to easily build Windows service application. These classes are contained in the System.ServiceProcess assembly that must be referenced by the project in VS .NET that comprises the service. Fortunately, VS .NET provides project templates for each .NET language accessible from the New Project dialog that reference the needed assemblies and can jump start the development process.
Because of the object-oriented nature of the .NET Framework, it's not surprising that a Windows services application in the .NET Framework primarily consists of a class (a "service class") derived from the ServiceBase class, the core class in the System.ServiceProcess namespace. This service class is then used to override methods such as OnStart, OnStop, and others used to control the service and defined in the base class. In addition, the service typically contains a Sub Main that is called when the executable is invoked, and is used to start the service class by invoking the shared Run method of the ServiceBase class.
In order to create a robust service, however, developers often need to go beyond these basics. In the remainder of this article, I'll walk through five characteristics that every good service needs, and give you some direction on their implementation. A completed skeleton for a Windows service that includes these features can be seen in Listing 1.