This documentation is archived and is not being maintained.

Create Windows Services

Visual Studio .NET 2003
This article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.

December 2001

Create Windows Services

Create, install, and uninstall your own Windows Service with VB.NET.


by Billy Hollis

Technology Toolbox

One powerful new feature of Visual Basic .NET is the capability to create a Windows Service. Windows NT and Windows 2000 use services extensively to implement functionality that needs to be widely available. A few examples include plug-and-play device detection, running message queues, file indexing, and task scheduling. In this column, I'll discuss what a Windows Service is and show you the basics of creating a simple one.

Those of us who go back far enough can remember applications that were "Terminate and Stay Resident" on DOS platforms. These programs operated in the background while a user did something else in the foreground. Operating systems are more sophisticated now, particularly at multitasking. The idea of a program operating in the background has evolved on Windows systems to the concept of a Windows Service. These programs were first available on Windows NT, dubbed NT Services. With the advent of Windows 2000, the name was changed to Windows Services.

A typical Windows 2000 installation can contain several dozen services. In addition to the services the operating system installs itself, programs such as SQL Server install their own Windows Services to implement functionality that must be available to all users.

Windows Services aren't available on Windows 9x or Windows Millennium Edition (Me). The examples in this column won't work on these operating systems even though the .NET Framework runs on Windows 98 and Windows Me. You need to use Windows 2000 Professional or Server to take advantage of Windows Services.

A Windows Service differs from a typical Windows program in several ways. First, a Windows Service can start before a user logs on. The system maintains a list of Windows Services that start at bootup time. (You can also install services so they don't start at bootup; in this case, they require a manual startup.) Also, a Windows Service might run under a different account than the currently logged-on user. Most Windows Services provide functionality that needs to be running all the time and, as mentioned, some load before a user logs on, so these services can't depend on a user being logged on to run.

Second, a Windows Service has its own process—it doesn't run in the process of a program communicating with it. Also, a Windows Service typically has no user interface. It might run in an account different from the current user, so the calls to put up a user interface might fail because they're out of context. Although it's possible to set up a Windows Service with a user interface, I don't recommend it.

Finally, a Windows Service requires a special installation procedure. You can't run it by simply clicking on a compiled EXE; instead, a Windows Service works with a program called a Service Control Manager. This program is required to provide an interface to the Windows Service. External programs needing to communicate with a Windows Service (for example, to start or stop the service) must go through the Service Control Manager.

Develop a Windows Service

Prior to .NET, Windows Services usually were developed in C++. Some third-party products were available to allow developers to use VB6 and earlier to create a Windows Service, but because it's so hard for VB6 to get to the system-level information needed to provide a service's functionality, developers didn't use this approach commonly.

Developing Windows Services changes completely in .NET. VB.NET is as good a choice as any other .NET language for developing a Windows Service. As with many areas of advanced functionality, the reason you can use VB.NET for this purpose is because base classes in the .NET Framework take care of the system-level interfacing. You need two base classes to create a Windows Service in VB.NET: System.ServiceProcess.ServiceBase and System.Configuration.Install.Installer.

System.ServiceProcess.ServiceBase provides the base class for the service itself. The class that inherits from this class contains the logic that runs in the service. System.Configuration.Install.Installer provides the interface necessary to get the service installed under Windows 2000 and NT. It isn't typically necessary to put any logic in your installer class.

As is typical in VB.NET, a project type for a Windows Service creates a class inheriting from ServiceBase. However, you must arrange to add the Installer class to your project manually. I'll show you an example—the beep service—that covers how to do that. Your service's only function is to beep every three seconds. Although this might be the most annoying Windows Service you ever create, it's excellent for stepping through the process of creating, installing, and starting a Windows Service. It contains little logic, and you can tell easily when it's running.

A Windows Service has a special installation procedure that handles all the operating-system communications necessary to execute a service. A special command-line program in .NET named InstallUtil.exe installs and uninstalls Windows Services produced in .NET. The beep service example uses InstallUtil.exe for both of these purposes. You can also review the development cycle for a Windows Service (see Figure 1).

 
Figure 1. Walk Through a Windows Service's Development Cycle.

Unlike most .NET programs, you can't simply click on a Windows Service's EXE to run it. Windows Services must be started and stopped, which can happen automatically. You can configure a Windows Service to start automatically at bootup, and of course it stops when a system is shut down. But a Windows Service can also accept instructions to start and stop, and the beep service example uses Windows 2000's built-in capabilities to perform these operations.

Note a couple implications and limitations before you get started. First, you shouldn't create a public interface for the class implementing the service. Although the result will compile if you add public properties and methods, the way a service is accessed provides no mechanism for accessing a public interface. Second, you can't debug the project in the environment you'd use for a .NET program. You must install and start the service before debugging it.

Create the Beep Service

Get started by creating a new project in Visual Studio with the type Windows Service. Name the project BeepService, then go to the design surface for the Service1 component. Open the Toolbox and click on the Components tab. Drag a Timer control from the Toolbox onto the Service1 component. It appears on the design surface with the name Timer1. (Important: Do not drag a Timer control from the Windows Forms tab; it won't function properly in a Windows Service.)

In the Properties window for Timer1, change the Interval property to a value of 3000. (That's 3,000 milliseconds, which causes the timer to fire every three seconds.) Then go back to the code for Service1.vb. Enter this code in the OnStart event:

Timer1.Enabled = True

Enter this code in the OnStop event for the class:

Timer1.Enabled = False

To create an Elapsed event for the timer, highlight Timer1 in the left-hand dropdown box at the top of the code editor window, then select the Elapsed event in the right-hand dropdown. Place this line of code in the Elapsed event:

Beep()

Now add an installer to the project. Go back to the design surface for Service1 and right-click on it. Select Add Installer, which creates a new component called ProjectInstaller and adds it to the project.

Highlight the ServiceProcessInstaller1 control on the ProjectInstaller design surface. Change the Account property in its Properties window to LocalSystem. Then highlight the ServiceInstaller1 control. In its Properties window, change the ServiceName property to BeepService. Now build the project. This creates an EXE for the service.

Now you're ready to install the service. As of VS.NET beta 2, you must start the utility for doing this, InstallUtil.exe, from a command line. InstallUtil.exe is located in C:\WINNT\Microsoft.NET\Framework\v1.0.2914 (as of beta 2).

Start up a DOS-style command window and change the current directory to C:\WINNT\Microsoft.NET\Framework\v1.0.2914. As an alternative to using the DOS-style command window used normally in Windows, you can get a special .NET command window that already has utilities such as InstallUtil.exe in its path (this way, you don't have to navigate to the preceding directory to use InstallUtil.exe). You get to this special .NET command window by selecting Start | Microsoft Visual Studio.NET 7.0 | Visual Studio.NET Tools | Visual Studio.NET Command Prompt.

After getting one of the two command windows, enter a command such as this:

InstallUtil.exe {path for BeepService.exe}

The path for the Windows Service executable varies depending on where you put your BeepService project. Remember that .NET places executable modules in a \bin subdirectory under the project directory. If the executable's path is complex, you might want to copy the executable to a simpler path such as C:\MyServices. In this case, the command to install the service would look like this:

InstallUtil.exe
   C:\MyServices\BeepService.exe

You should look at the messages generated by InstallUtil.exe to ensure the service installed successfully.

Start BeepService

You can create a customized "control panel" to start and stop the service. But for this example, you'll use Windows' built-in Service Control Manager. These directions assume you're using Windows 2000, but the steps for Windows NT are similar.

Bring up the Control Panel and select Administrative Tools. Next, select Services (see Figure 2). Note the presence of the BeepService program you installed earlier; if BeepService doesn't appear, the installation wasn't successful.

Start BeepService by right-clicking on it and selecting Start. Your computer begins to beep every three seconds. You can stop the service by right-clicking on BeepService and selecting Stop.

Uninstalling the service is similar to installing it. You do this in a command window; use the same command used as the one for installation, except include the option "/u" just before the path for the service. Assuming you placed BeepService.exe in the C:\MyServices directory, the command to uninstall BeepService would look like this:

InstallUtil.exe /u
   C:\MyServices\BeepService.exe

Once you uninstall BeepService, it no longer shows up in the list of available services to start and stop.

You must uninstall and reinstall a Windows Service every time you make changes to it. It's also a good idea to uninstall Windows Services you're using for testing or learning as soon as you're finished with them.

Important: You should close the Services screen (shown in Figure 2) every time you uninstall a service. If the Services screen remains open, reinstalling your service might be difficult. After reinstalling the service, you can reopen the Services program from Administrative Tools.

If you need background processing or monitoring capabilities in one of your applications, a Windows Service might be the answer. These services are easy to create, as this column has shown. Windows Services are a bit tedious to install and uninstall, but otherwise they work much like typical .NET programs.

About the Author
Billy Hollis is an author and software developer from Nashville, Tenn. Billy is the coauthor of the first book ever published on Visual Basic .NET, VB.NET Programming With the Public Beta (Wrox Press). He's a frequent speaker at conferences, including Comdex, VBITS, PDC, and the .NET Developer Tour. You can contact him at bhollis@dotnetmasters.com.

Show: