Creating a Windows Service Application

   


Creating a Windows Service Application

Create and manipulate a Windows service: Write code that is executed when a Windows service is started or stopped .

In this section, you'll use the ServiceBase class to create a Windows service application. You'll learn

  • About the ServiceBase class and its functionality

  • How the SCM interacts with a Windows service derived from the ServiceBase class

  • How to create a Windows service by deriving a class from the ServiceBase class

The System.ServiceProcess.ServiceBase Class

Programmatically, a Windows service is a class that derives its basic functionality from the ServiceBase class of the System.ServiceProcess namespace. The ServiceBase class provides its derived classes with some well-known methods and properties. The SCM knows these methods and properties and uses them to communicate with the Windows services. Table 6.1 lists the important members of the ServiceBase class.

Table 6.1. Important Members of the ServiceBase Class

Member Name

Type

Description

AutoLog

Property

When set to true, automatically logs the call to OnStart() , OnStop() , OnPause() , and OnContinue() methods in the Application event log.

CanPauseAndContinue

Property

When set to true, indicates that the service can be paused and resumed.

CanShutdown

Property

When set to true, indicates that the service should be notified when the system is shutting down.

CanStop

Property

When set to true, indicates that the service can be stopped once it has started.

EventLog

Property

Specifies an event log that can be used to write customized messages to the Application event log on method calls such as OnStart() and OnStop() .

OnContinue()

Method

Specifies the actions to take when a service resumes normal functioning after being paused.

This method is executed when the SCM sends a continue command to the Windows service.

OnPause()

Method

Specifies the actions to take when a service pauses.

This method is executed when the SCM sends a pause command to the Windows service.

OnStart()

Method

Specifies the actions to take when a service starts running.

This method is executed when the SCM sends a start command to the Windows service.

OnStop()

Method

Specifies the actions to take when a service stops running.

This method is executed when the SCM sends a stop command to the Windows service.

Run()

Method

Provides the main entry point for a service executable.

ServiceName

Property

Specifies a name that identifies the service.

EXAM TIP

Writing to a Custom Event Log With the help of the AutoLog and the EventLog properties of the ServiceBase class, you can write messages only to the Application event log. If you want to write entries to a different event log, you should create a new EventLog component and the OnStart() , OnStop() , and so on methods to explicitly post entries to that log.


Understanding How the SCM Interacts with a Windows Service

A Windows service application defines one or more classeseach defining a Windows service. Only one of these classes can define a Main() method, which is the main entry point for the application. The Main() method specifies which Windows services should run by passing the instances of the Windows service to the static Run() method of the ServiceBase class.

The Run() method does not actually start the Windows service; instead, the Run() method just passes the reference of the Windows service objects to the SCM. The SCM uses these objects to send messages to the Windows service.

Figure 6.2 illustrates how the SCM interacts with a Windows service derived from the ServiceBase class.

Figure 6.2. The ServiceBase class provides the functionality that enables a Windows service application to interact with the SCM.

When the SCM sends a start message to the Windows service, the following things happen:

  1. The SCM finds the path of the Windows service application's executable file from the Windows service database.

  2. SCM creates a Windows service process by executing the Main() method defined in the Windows service executable.

  3. The Main() method of the Windows service executable creates one or more instances of the Windows service class and passes their references to the SCM through the static Run() method of the ServiceBase class. The SCM uses these references to send messages to the Windows service.

  4. The handler associated with the start messagethe OnStart() methodis executed. The OnStart() method executes the code required for a Windows service to carry out its tasks , such as listening to a port for incoming requests , logging events to the event log, spooling print jobs, and so on.

After the Windows service is started, SCM can use its reference to send various messagessuch as pause, continue, and stopto the Windows service. These messages invoke the OnPause() , OnContinue() , and OnStop() methods of the Windows service, respectively.

Not all services implement the OnPause() , OnContinue() , and OnStop() methods. Whether a service needs to implement these methods depends on the CanPauseAndContinue and CanStop properties of a Windows service. If these properties are true, the SCM can invoke the OnPause() , OnContinue() , and OnStop() methods. But not every service implements this functionality. Some common examples of services that do not enable pausing or stopping include the Event Log, the Plug and Play, and the Security Accounts Manager services, which can neither be paused nor stopped, as well as the Print Spooler and the System Event Notification services, which can be stopped but not paused.

NOTE

Controlling a Windows Service If you set any of the CanStop , CanShutdown , or CanPauseAndContinue properties for a Windows service to true, you also must implement a corresponding handler method (such as OnStop() , OnPause() , OnContinue() , and so on). Otherwise , when SCM sends any of these messages, the Windows service will throw an exception and ignore the command.


There is no CanStart property in the ServiceBase class. This means that not starting is not an option for a Windows service. A Windows service class must provide an OnStart() method; otherwise, the base class version of the method is called.

When SCM sends a stop message to the Windows service, the associated handler OnStop() method is executed. After this, the Windows service process is unloaded from the memory.

Creating the OrderService Application

To demonstrate how the Windows services are created, I'll create an OrderService that listens for XML files containing order information in a particular disk directory ( c:\orders ). As soon as an XML file is created in the directory, the service reads the files and, based on its data, creates a new record in the Orders table of the Northwind database. This type of application is typically used for updating orders received from the Internet, business partners , and from legacy applications.

Step By Step 6.1 shows how to create the OrderService application.

STEP BY STEP

6.1 Creating a Windows Service Application

  1. Launch Visual Studio .NET. Select File, New, Blank Solution, and name the new solution 310C06 . Click OK.

  2. Add a new project to the solution. In the Add New Project dialog box, select Visual Basic Projects as the project type and Windows Service as the template. Name the project StepByStep6-1 , as shown in Figure 6.3.

    Figure 6.3. The Windows Service template allows you to easily create a Windows service application.

  3. The Windows service project contains a file named Service1.vb . Rename this file OrderService.vb . Click on the designer surface and then use the Properties windows to set the Name and ServiceName properties to OrderService . Set the CanPauseAndContinue property to True . Note that the AutoLog and the CanStop properties are already True , as shown in Figure 6.4.

    Figure 6.4. You can set various properties of a Windows service through the Properties window.

  4. Switch to the code view and change all occurrences of Service1 to OrderService . You'll need to expand the Component Designer generated code region to do so. Add the following Imports statements to the code:

     Imports System.Data.SqlClient Imports System.IO 
  5. Switch to the design view. Open the Visual Studio .NET toolbox. From its components tab (see Figure 6.5), drag and drop a FileSystemWatcher component onto the surface of the OrderService component.

    Figure 6.5. The FileSystemWatcher component listens to the file system and raises events when there are any changes.

  6. Access the Properties window for the FileSystemWatcher component and change its Name property to fswOrders , Filter property to *.xml , and Path property to c:\orders .

  7. Switch to code view. Select fswOrders in the classname drop-down list at the top of the code editor, and then select Created in the method name drop-down list. This will create and hook up an event handler for the Created event. Add the following code to the event handler:

     Private Sub fswOrders_Created(_  ByVal sender As Object, _  ByVal e As System.IO.FileSystemEventArgs) _  Handles fswOrders.Created     Dim dsOrders As DataSet = New DataSet("Orders")     ' Read the contents of the XML file     ' into the Orders DataSet     dsOrders.ReadXml(e.FullPath)     ' Set up the database connection string     Dim strConn As String = "data source=(local);" & _      "initial catalog=Northwind;" & _      "integrated security=SSPI"     Dim strOrderQuery As String = _      "SELECT * FROM Orders"     ' Create a DataAdapter for the Orders     ' table of the Northwind database     Dim daOrders As SqlDataAdapter = _      New SqlDataAdapter(strOrderQuery, strConn)     ' Automatically generate the update     ' command to reconcile the changes     ' made to the DataSet     Dim cbOrders As SqlCommandBuilder = _      New SqlCommandBuilder(daOrders)     ' Update the DataSet     daOrders.Update(dsOrders, "Orders")     daOrders.Dispose()     Dim fi As FileInfo = New FileInfo(e.FullPath)     ' Create a subdirectory named "Updated"     ' if it does not already exists     fi.Directory.CreateSubdirectory("Updated")     ' Copy the processed XML file to updated     ' directory, overwriting if needed     File.Copy(e.FullPath, fi.DirectoryName & _      "\Updated\" + fi.Name, True)     ' Delete the XML file from its     ' original location     fi.Delete() End Sub 
  8. In the code, search for the skeletons of the OnStart() and OnStop() methods and modify them as shown here:

     Protected Overrides Sub OnStart(_  ByVal args()As String)     fswOrders.EnableRaisingEvents = true End Sub Protected Overrides Sub OnStop()     fswOrders.EnableRaisingEvents = False End Sub 
  9. Add the following code to the OrderService class to override the OnPause() and the OnContinue() methods of the base class:

     Protected Overrides Sub OnPause()     fswOrders.EnableRaisingEvents = False End Sub Protected Overrides Sub OnContinue()     fswOrders.EnableRaisingEvents = True End Sub 
  10. Set the startup object for the project to OrderService.

  11. Build the project. This step creates the OrderService Windows service application.

When you create a new project based on the Windows Service template, Visual Studio .Net automatically inserts a class that derives from the System.ServiceProcess.ServiceBase class in the project. In order to respond to various events raised by the SCM messages, I have overridden the base class version of the OnStart() , OnStop() , OnPause() , and OnContinue() methods.

In Step By Step 6.1, I'm using the FileSystemWatcher component. This component watches for any changes in the file system and raises events when a file or directory changes. In this example, I have initialized the FileSystemWatcher component in such a way that it just watches for the creation of XML files in a directory named c:\orders . I have also instructed the FileSystemWatcher component to exclude any subdirectories of c:\orders to narrow down the scope of notifications.

When an XML file is created in the c:\orders directory, the FileSystemWatcher component raises the Created event. I am using the fswOrders_Created() event handler to retrieve the order information from the newly created XML file and insert this information as a new order to the Order table of the Northwind database.

Table 6.2 lists some important members of the FileSystemWatcher component.

Table 6.2. Important Members of the FileSystemWatcher Class

Member

Type

Description

Changed

Event

When a file or directory in the specified Path is changed this occurs.

Created

Event

When a file or directory in the specified Path is created this occurs.

Deleted

Event

When a file or directory in the specified Path is deleted this occurs.

EnableRaisingEvents

Property

Specifies whether the component is enabled. If its value is false, the component does not receive any events.

Error

Event

Occurs when the internal buffer of the component overflows.

Filter

Property

Specifies which files are monitored in a directory. Its default value is *.* , which monitors for all types of files.

IncludeSubdirectories

Property

Specifies whether the subdirectories within the specified path should be monitored.

InternalBufferSize

Property

Specifies the size of the internal buffer.

NotifyFilter

Property

Specifies the type of file system changes to monitor. Its value is a combination of values (each separated by a comma) from the NotifyFilters enumeration. Its default value is FileName, DirectoryName, LastWrite , which means that the component monitors for any changes in the filename, directory name, and the date and time of the last write operation on the files or directory.

Path

Property

Specifies the path of the directory to watch.

When a file or directory in the specified Path is renamed this occurs.

SynchronizingObject

Property

Specifies the object that is used to marshal the event handler calls.

WaitForChanged()

Method

This method is a synchronous method that returns a structure that contains specific information on the file system change.

WARNING

The FileSystemWatcher Component Might Lose Track of Changes The FileSystemWatcher component stores the file system changes in an internal buffer whose size is set by a property named InternalBufferSize before it acts on those changes. If there are too many changes in a short time, this buffer can overflow and cause the FileSystemWatcher component to lose track of the file system changes. The default size of this buffer is 8192 bytes. You should not arbitrarily increase the size of this buffer because this buffer is maintained in non-paged memory and increasing its size would directly impact the performance of other applications. Instead, you should use the Path , NotifyFilter , and IncludeSubdirectories properties to narrow down the scope of notifications that the FileSystemWatcher component receives.


Compilation of the StepByStep6_1 project creates an executable file just like other Windows applications. However, you cannot directly run this executable. If you try doing so, you'll get a Windows service start failure error with the following message:

 Cannot start service from the command line or a debugger. A Windows Service must first be installed (using installutil.exe) and then started with the Server Explorer, Windows Services Administrative tool or the NET START command 

Apparently, you need to install a Windows service application before you can start it. You'll learn how to do that in the following section.


   
Top


MCAD. MCSD Training Guide (Exam 70-310. Developing XML Web Services and Server Components with Visual Basic. NET and the. NET Framework)
MCAD/MCSD Training Guide (70-310): Developing XML Web Services and Server Components with Visual Basic(R) .NET and the .NET Framework
ISBN: 0789728206
EAN: 2147483647
Year: 2002
Pages: 166

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net