2
Developing
a Windows
Service
CERTIFICATION OBJECTIVES
2.01 Creating and Manipulating
a Windows Service
2.02 Writing Code That Is Executed
When a Windows Service
Is Started or Stopped
✓
Two-Minute Drill
Q&A
Self Test
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind / 222653-6 /
Chapter 2
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind / 222653-6 /
Chapter 2
P:\010Comp\CertPrs8\653-6\ch02.vp
Wednesday, October 30, 2002 9:47:02 AM
Color profile: Generic CMYK printer profile
Composite Default screen
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind /
222653-6 / Chapter 2
I
n this chapter, you will learn about the Windows Services, previously known as NT
Services. A Windows service is any application that needs to execute for long periods of
time in its own session on a server. A Windows service starts without any intervention
from a user when the server’s operating system boots, and it can authenticate using either the
local SYSTEM account or a domain user’s account; in this way the Windows service can use
the security context that best fits its purpose. The Windows Services also include software
applications that have no interaction with the screen on the server where they are executed,
such as an e-mail service or a web service.
Note that at this time, support for Windows developing Services is available only
in the Enterprise Edition. Support is not available in the Standard Edition of Visual
Studio .NET. The examples in this chapter are written using the Enterprise Edition
of Visual Studio .NET.
CERTIFICATION OBJECTIVE 2.01
Windows Services
The Windows Services technology is one of the important building blocks that you
will use when building applications that must always run on the server, and that
perform services for many users. Examples of Windows services are applications such
as Internet Information Services (IIS), the Tardis clock service, and Microsoft Simple
Mail Transport Protocol (SMTP). These services all run in the background, perform
services for potentially many users or systems, and have no user interface. Windows
services are managed through management applications that are specifically written to
interact with them, or you can use the Services application that is available from the
operating system.
I have used the term “server” to refer to the computer where a Windows service
is running, but that is not the whole story. The Windows NT and Windows 2000
families of operating systems, as well as Windows XP Professional, all can run
Windows Services. However, Windows 9x, Windows Me, and Windows XP Home
2
Chapter 2: Developing a Windows Service
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind /
222653-6 / Chapter 2
P:\010Comp\CertPrs8\653-6\ch02.vp
Wednesday, October 30, 2002 9:47:02 AM
Color profile: Generic CMYK printer profile
Composite Default screen
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind / 222653-6 /
Chapter 2
edition do not have the ability to run the Windows Services as part of the operating
system. In these operating systems, a Windows service is executed as a user process
that requires a user to be logged on to the computer.
Windows services are used to extend the operating system; they are similar to
daemons in Unix.
Take a look at the Services application and what you can control in the services
running on a server. If you are running Windows 2000 or Windows XP Professional,
you access the Services application from the Run | Programs | Administrative Tools
menu. If the Administrative Tools menu is missing in your Windows 2000 or XP
Professional operating system, you will need to make it available by selecting Run |
Settings | Task Bar & Start Menu.
After you select Services in the Administrative Tools menu (shown in the
following illustration), you will see a list of services that are installed on your
server along with the current status of each service (shown in Figure 2-01),
Windows Services
3
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind / 222653-6 /
Chapter 2
P:\010Comp\CertPrs8\653-6\ch02.vp
Wednesday, October 30, 2002 9:47:02 AM
Color profile: Generic CMYK printer profile
Composite Default screen
4
Chapter 2: Developing a Windows Service
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind /
222653-6 / Chapter 2
indicating whether it is stopped, paused, running, or disabled. You can also see
(from the startup type) if the service will automatically start with the operating
system, or if it must be manually started.
The listing of Windows Services is all-inclusive, meaning that all the known
information about each service is displayed in the Services application. Further, the
FIGURE 2-1
The Services application
P:\010Comp\CertPrs8\653-6\ch02.vp
Wednesday, October 30, 2002 9:47:03 AM
Color profile: Generic CMYK printer profile
Composite Default screen
Windows Services
5
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind / 222653-6 /
Chapter 2
Description field is sometimes very long and contains the long form of the service’s
name. In order to control the properties of a Windows service, you double-click the
service in the Services application. Here, you can see the properties of the World
Wide Web Publishing service, which is the name of the Web server part of IIS:
As you can see, the properties that can be set on the General tab include the display
name of the service as well as the description. You can also set the startup property
to inform the operating system what type of startup you wish to have. The options are:
■
Automatic The service will be started as part of the operating system’s boot
sequence.
■
Manual The service is enabled and will be started by the administrator
(or by another service that requires it) when needed.
■
Disabled The service will never be started unless the startup property
is changed.
Set a service to Disabled if you want to be sure that it never starts
automatically, but set it to Manual if you want the service to start
if another service depends on it.
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind / 222653-6 /
Chapter 2
P:\010Comp\CertPrs8\653-6\ch02.vp
Wednesday, October 30, 2002 9:47:03 AM
Color profile: Generic CMYK printer profile
Composite Default screen
6
Chapter 2: Developing a Windows Service
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind /
222653-6 / Chapter 2
In the Service Status area, you will see the current state of the service as well as
the controls to Start, Pause, Stop, or Resume the service. The Start Parameters field
is used to pass parameters to the service when it starts.
The Log On pane defines the account that will be used by the service to establish a
security context. This service is not started when a user logs in to the server; rather, the
service must authenticate to the server in order to get access to resources like memory,
the processor, and the network. The default security account is the local SYSTEM
account, which is the highest-permission account on any Windows server. Using
the SYSTEM account is a very good idea as long as the service does not have to
access resources over the network. Because the SYSTEM account has such powerful
permissions, it is limited to the local system only, meaning that a service cannot access
any remote resources using it. If the service requires access to remote resources, you
should use a domain user’s account to start the service. You can also associate the
service with a specific hardware profile if specific settings are needed for the service.
P:\010Comp\CertPrs8\653-6\ch02.vp
Wednesday, October 30, 2002 9:47:03 AM
Color profile: Generic CMYK printer profile
Composite Default screen
Windows Services
7
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind / 222653-6 /
Chapter 2
If the Windows service needs to access remote resources, you need to associate
it with a user account because the SYSTEM account cannot be used to access
remote resources.
The Recovery pane gives you control over what action to take if the service fails.
The settings are for the first and second failures as well as any subsequent failures.
The Dependencies pane enables you to view the services that depend on your
services as well as the services your service depends on. The system checks
dependencies to make sure your service doesn’t start unless some other service
has started first.
P:\010Comp\CertPrs8\653-6\ch02.vp
Wednesday, October 30, 2002 9:47:03 AM
Color profile: Generic CMYK printer profile
Composite Default screen
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind /
222653-6 / Chapter 2
8
Chapter 2: Developing a Windows Service
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind /
222653-6 / Chapter 2
When you start building Windows services,
the first question that usually pops up is: What
can you use service for? The answer is actually
simple—anything!
Okay, I hear you, that is an unfair answer, but
it is true. Some of the most exciting aspects
of the Windows operating system have been
implemented as Windows services. For example,
IIS is implemented as a service, as is Microsoft
SQL Server and Microsoft Exchange Server.
These are large and powerful applications, but
they are implemented as services so that they
can act together with the operating system,
with no user intervention at all.
I usually recommend to my students that they
begin by building services that perform some
small but interesting service for them. The
following are some Windows services that have
been built in just a week’s time: a time server
that synchronizes the computer with a Network
Time Protocol (NTP) server, a card deck service
that returns a random card, a simple web
server...the list goes on.
Use the information in this chapter to build
software that moves you and your projects
forward.
FROM THE CLASSROOM
P:\010Comp\CertPrs8\653-6\ch02.vp
Wednesday, October 30, 2002 9:47:03 AM
Color profile: Generic CMYK printer profile
Composite Default screen
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind / 222653-6 /
Chapter 2
The majority of these settings are controlled through the installation process. I will
spend more time on this topic later in this chapter.
Now that you have seen the Services application, proceed to build a small service
to look at the mechanics of building and installing a service.
CERTIFICATION OBJECTIVE 2.02
Developing a Windows Service
In this section, you are going to build a Windows service that logs messages in the
event log as its only function. We’ll set this limitation for now so that you can look
at the different aspects of the service. In order to build a Windows service, you
will need to have a minimum of the Professional Edition of Visual Basic .NET
(the Standard Edition does not support Windows Services development).
EXERCISE 2-1
The Windows Service Skeleton
1.
Create a new project in Visual Studio .NET. Make it a Visual Basic .NET
project and select Windows Service from the Template list as shown here.
Give the project the name ServiceOne and save it to the C:\VB directory.
Developing a Windows Service
9
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind / 222653-6 /
Chapter 2
P:\010Comp\CertPrs8\653-6\ch02.vp
Wednesday, October 30, 2002 9:47:03 AM
Color profile: Generic CMYK printer profile
Composite Default screen
2.
Once the project is created, you should change the name of the Windows
service to the name you have decided on, in our case, ServiceOne. To change
the name, select the service in the Property Explorer and change the (name)
and ServiceName properties as shown here:
3.
Right-click the project in the Solution Explorer and select Properties in the
context menu. In the Project Properties dialog, change the Startup Object to
ServiceOne and click OK. This step tells the compiler what class contains the
startup code; if you don’t change this property, the project will not compile
but will report a missing Sub Main().
4.
Click “click here to switch to code view” in Design view to open the code
module.
Note that as you changed the name of the Windows service, Visual Studio
.NET adjusted the names in the source code.
10
Chapter 2: Developing a Windows Service
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind /
222653-6 / Chapter 2
P:\010Comp\CertPrs8\653-6\ch02.vp
Wednesday, October 30, 2002 9:47:04 AM
Color profile: Generic CMYK printer profile
Composite Default screen
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind / 222653-6 /
Chapter 2
5.
The code that was created by the Windows Service Wizard is shown in the
following code listing:
Imports System.ServiceProcess
Public Class ServiceOne
Inherits System.ServiceProcess.ServiceBase
#Region " Component Designer generated code "
Public Sub New()
MyBase.New()
' This call is required by the Component Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call
End Sub
'UserService overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
' The main entry point for the process
<MTAThread()> _
Shared Sub Main()
Dim ServicesToRun() As System.ServiceProcess.ServiceBase
' More than one NT Service may run within the same process. To add
' another service to this process, change the following line to
' create a second service object. For example,
'
' ServicesToRun = New System.ServiceProcess.ServiceBase () _
' {New Service1, New MySecondUserService}
'
ServicesToRun = New System.ServiceProcess.ServiceBase()
{
New ServiceOne()
}
System.ServiceProcess.ServiceBase.Run(ServicesToRun)
End Sub
'Required by the Component Designer
Private components As System.ComponentModel.IContainer
' NOTE: The following procedure is required by the Component Designer
' It can be modified using the Component Designer.
' Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Developing a Windows Service
11
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind / 222653-6 /
Chapter 2
P:\010Comp\CertPrs8\653-6\ch02.vp
Wednesday, October 30, 2002 9:47:04 AM
Color profile: Generic CMYK printer profile
Composite Default screen
Private Sub InitializeComponent()
'
'ServiceOne
'
Me.ServiceName = "ServiceOne"
End Sub
#End Region
Protected Overrides Sub OnStart(ByVal args() As String)
' Add code here to start your service. This method should set things
' in motion so your service can do its work.
End Sub
Protected Overrides Sub OnStop()
' Add code here to perform any tear-down necessary to stop
' your service.
End Sub
End Class
The bolded text in the preceding listing is the one area that needs to be
modified after the service is constructed by Visual Studio .NET. You will
need to make sure that the object that is instantiated is the class you are
building—the Visual Studio .NET editor does not correctly update the
name when you change the name of the class.
Visual Studio .NET does not change the class name that is instantiated in the
Main()
method.
You are going to give this service some low-level functionality that will record
events in an event log. The Windows service has predefined events that you
want to write code for: service start, stop, and pause, among others. We’ll
discuss events in greater detail later in the chapter. For now, notice that these
events are points in the life of the Windows service, and the Windows service
code that is generated by Visual Studio .NET includes the handlers for two
of those three events: OnStart() and OnStop(). You will write code in
these event handlers so that you can see how the service operates.
6.
The first thing you must do before you can start writing information into
the event log is to make sure that there is an event log and to connect to it.
To do this, switch to the Design view of the Windows service and open up
the Toolbox, then select the Components tab in the Toolbox. Drag and drop
the EventLog component on to the Windows Service Design window, where
it will be called EventLog1. The result is shown here:
12
Chapter 2: Developing a Windows Service
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind /
222653-6 / Chapter 2
P:\010Comp\CertPrs8\653-6\ch02.vp
Wednesday, October 30, 2002 9:47:04 AM
Color profile: Generic CMYK printer profile
Composite Default screen
7.
The logical place to add code that will control the use of the event log you
added to the project is in the constructor of the Windows service class; this
way, the event log is configured for use as soon as the service starts. The
following code segment shows how to open an event log:
Public Sub New()
MyBase.New()
' This call is required by the Component Designer.
InitializeComponent()
' Add any initialization after the
InitializeComponent() call
' Test if the event log exists; if not, create it
If (Not
System.Diagnostics.EventLog.SourceExists("ServiceOne")) Then
EventLog.CreateEventSource("ServiceOne",
"ServiceOneLog")
End If
' Set the source and log properties for the event log
EventLog1.Source = "ServiceOne"
EventLog1.Log = "ServiceOneLog"
End Sub
The event log is exposed to our Windows service through the System.Diagnostics
namespace. By verifying that the event log exists and creating it if it does not,
you are guaranteed that, when you associate the EventLog1 component that
was added to the service with our event log, the log will be there.
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind / 222653-6 /
Chapter 2
Developing a Windows Service
13
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind / 222653-6 /
Chapter 2
P:\010Comp\CertPrs8\653-6\ch02.vp
Wednesday, October 30, 2002 9:47:04 AM
Color profile: Generic CMYK printer profile
Composite Default screen
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind /
222653-6 / Chapter 2
8.
Now you will add code to the OnStart() event handler to write an event to
the event log. The following code segment shows how to do this:
Protected Overrides Sub OnStart(ByVal args() As String)
' Add code here to start your service. This method should set things
' in motion so your service can do its work.
EventLog1.WriteEntry("ServiceOne is starting")
End Sub
9.
Add the following to the OnStop() method:
Protected Overrides Sub OnStop() ' Add code here to perform any
tear-down
' necessary to stop your service.
EventLog1.WriteEntry("ServiceOne is stopping") End Sub
10.
Build the Windows service to make sure it compiles by selecting Build
Solution from the Build menu. The Windows service cannot be run directly
from Visual Studio .NET but needs to be registered in the Windows Registry
and started by the Service Manager. If you try to run it directly, the message
shown here is the result:
The solution is to include an Installer project with the Windows service
project.
11.
To add the Installer: switch to the Design view, right-click the background,
and select Add Installer from the context menu as shown next:
14
Chapter 2: Developing a Windows Service
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind /
222653-6 / Chapter 2
P:\010Comp\CertPrs8\653-6\ch02.vp
Wednesday, October 30, 2002 9:47:04 AM
Color profile: Generic CMYK printer profile
Composite Default screen
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind / 222653-6 /
Chapter 2
The result is shown in the following illustration, where you can see the
Design view of the new ProjectInstaller.vb file. You will notice that there are
two instances of the ProjectInstaller class: first the ServiceInstaller1 that will
install our Windows service and then the ServiceProcessInstaller1 that is used
to install the Windows service’s associated process.
12.
Change the name of the ServiceInstaller1 component to ServiceOneInstaller.
13.
Verify that the StartType property is set to Automatic.
Developing a Windows Service
15
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind / 222653-6 /
Chapter 2
P:\010Comp\CertPrs8\653-6\ch02.vp
Wednesday, October 30, 2002 9:47:05 AM
Color profile: Generic CMYK printer profile
Composite Default screen
16
Chapter 2: Developing a Windows Service
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind /
222653-6 / Chapter 2
14.
Right-click the ServiceOne project in the Solution Explorer and click
Properties in the context menu.
15.
Verify that ServiceOne is selected as the startup object on the General screen.
16.
Build the project. Now you have the Windows service built to the point that
it is ready to be installed. The installation on a server is performed by creating
a Setup project. This Setup project will register the Windows service with the
Windows Registry to make it runnable. To do this, you will
17.
Add a Setup and Deployment project to the solution by selecting Add Project |
New Project from the File menu.
18.
In the Add New Project dialog, select Setup And Deployment Projects from
the Project Types list, and select Setup Project from the Templates list.
P:\010Comp\CertPrs8\653-6\ch02.vp
Wednesday, October 30, 2002 9:47:05 AM
Color profile: Generic CMYK printer profile
Composite Default screen
19.
Name the Project ServiceOneSetup. Click OK.
The resulting solution is shown next:
20.
Right-click the ServiceOneSetup project and select Add | Project Output
from the context menu. This step will provide the information for the
installation process.
Developing a Windows Service
17
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind / 222653-6 /
Chapter 2
P:\010Comp\CertPrs8\653-6\ch02.vp
Wednesday, October 30, 2002 9:47:05 AM
Color profile: Generic CMYK printer profile
Composite Default screen
18
Chapter 2: Developing a Windows Service
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind /
222653-6 / Chapter 2
21.
The Add Project Output Group dialog box is displayed. Verify that the
ServiceOne Windows service is selected in the Project control and that
Primary Output is selected. Click OK.
22.
Now you need to add the directions that will install the Windows service.
Right-click the ServiceOneSetup project in the Solution Explorer and select
View | Custom Actions from the context menu as shown here:
P:\010Comp\CertPrs8\653-6\ch02.vp
Wednesday, October 30, 2002 9:47:06 AM
Color profile: Generic CMYK printer profile
Composite Default screen
Developing a Windows Service
19
CertPrs8 / MCAD/MCSD XML Web Services and Server Components Development with Visual Basic .NET / Lind / 222653-6 /
Chapter 2
23.
The Custom Actions editor is displayed.
24.
Right-click Custom Actions in the Custom Action editor. Select Add
Custom Action… from the context menu to open the dialog to select the
items in the project.
25.
Select and double-click the Applications Folder in the Look In: combo control.
26.
Select Primary Output From ServiceOne (Active). Click OK.
P:\010Comp\CertPrs8\653-6\ch02.vp
Wednesday, October 30, 2002 9:47:06 AM
Color profile: Generic CMYK printer profile
Composite Default screen