Creating a Windows Service by Using Visual Studio .NET

The .NET Framework classes include a set of base classes, in the System.ServiceProcess namespace, that provide the underlying functionality of a Windows service application. Visual Studio .NET offers a project template that automatically sets a reference to System.ServiceProcess and also provides you some boilerplate code. This section describes the default setup in detail. When you create a project by using the template, you need to concentrate only on the unique features that your application will implement.

When you create a new project in Visual Studio .NET and choose Windows Service as your project template, the project will initially look like Figure 1.2. The default project contains one component class module (with the default name Service1.vb). If you view the code inside Service1.vb (see Listing 1.1), you will notice that a class has been created (also using the default class name Service1). This class inherits from the System.ServiceProcess.ServiceBase namespace. The template also adds an Imports statement for the System.ServiceProcess namespace.

click to expand
Figure 1.2: Visual Studio .NET’s default project setup for a Windows Service application

Listing 1.1: Default Code for a Windows Service Application

start example
Imports System.ServiceProcess Public Class Service1     Inherits System.ServiceProcess.ServiceBase 'Component Designer generated code appears here 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 teardown necessary         ' to stop your service.     End Sub End Class
end example

If you expand the References node in the Solution Explorer window, you can see that a reference has been added for System.ServiceProcess.dll. Note that the .dll suffix is not present.

The default code also contains two procedure definitions for important methods of the ServiceBase class, OnStart and OnStop. You will add your custom code to these, and other methods, to implement the specific behavior of your Windows service application.

If you expand the region titled Component Designer Generated Code, you will see implementations for the New and Dispose methods, with code specific to how these standard Framework methods should be coded for a Windows service. There is also a Sub Main() procedure with some code needed for a Windows service to be started correctly (see Listing 1.2). The code in this procedure calls the Run method of the ServiceBase class and passes a reference to a new instance of your service. This is the code that enables your service to start when the operating system or a user invokes it.

Listing 1.2: Component Designer Generated Code

start example
' The main entry point for the process     <MTAThread()> _     Shared Sub Main()       Dim ServicesToRun() As _           System.ServiceProcess.ServiceBase       ' More than one NT Service may run in 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 Service1}       System.ServiceProcess.ServiceBase.Run(ServicesToRun)     End Sub
end example

Methods and Properties of the ServiceBase Class

Now that you have seen the basics required to create a Windows service application, you can concentrate on creating a service with custom functionality. To do this, you will provide custom implementations for methods of the parent ServiceBase class (see Table 1.1). The ServiceBase class also defines properties that you can set to affect the behavior of your service (see Table 1.2).

Table 1.1: Methods of the ServiceBase Class

Method Name

Description

OnContinue

Implement this method to run custom code when a service is resumed after being paused.

OnCustomCommand

Implement this method when you need custom actions that can be called programmatically by a ServiceController object.

OnPause

Implement this method to run custom code when a service is paused.

OnPowerEvent

Implement this method to run custom code when the computer’s power status has changed—for example, a laptop computer going into suspended mode.

OnShutdown

Implement this method to run custom code before the computer shuts down.

OnStart

Implement this method to run custom code when a service starts. It is preferred to put initialization code in this procedure rather than in the constructor (Sub New method).

OnStop

Implement this method to run custom code when a service is stopped.

Tip 

You will see how to implement the OnCustomCommand method later in this chapter, in the section titled “Executing Custom Commands for a Service.”

Note 

It is preferred to use the OnStart method for any code that must run when your service is started. Code in the constructor method, Sub New, runs when the service is instantiated, before it is completely started and running in the context of the Service Control Manager. Also, the Visual Studio .NET documentation states that “there is no guarantee the objects will be reinitialized when you restart a service after it has been stopped.”

Table 1.2: Properties of the ServiceBase Class

Property Name

Description

AutoLog

If this property is set to True, every time the service is started, stopped, paused, or continued, an entry will be written to the Windows Application event log. Set this property to False if you want to code custom log messages.

CanHandlePowerEvent

Set this to True if you have written custom code for the OnPowerEvent method. This will enable you to take special action if the computer that your service is running on experiences a change in power status—for example, a laptop computer going into suspended mode.

CanPauseAndContinue

Set this value to True if you want to allow your service to be paused.

CanShutdown

Set this to True if you have written custom code for the OnShutdown method. This will enable you to take special action before the computer shuts down.

CanStop

This value is usually set to True. It is set to False for some important operating system services, which should not be stopped by a user.

EventLog

If the AutoLog property is set to True, messages will be written to the Windows Application event log. If you set AutoLog to False, then you can specify a different event log for messages.

ServiceName

Gets or sets the service name.

Project Installer Classes

The Project Installers are “helper” classes that you add to your Windows service project. They provide important information that is used during the installation of your service application, such as the name that will be displayed in the Service Control Manager console, whether the service is started automatically or manually, and the security account. The security account is a Windows user login or system account that provides the identity and permissions that the Windows service will run with. Each Windows service project will have one instance of the ServiceInstaller class and one instance of the ServiceProcessInstaller class for each service that is included in the project.

When you are working in the Visual Studio .NET Integrated Development Environment (IDE), you can add ServiceInstaller components directly to your project from the Toolbox.

Note 

If you prefer, you can also create these objects in code. You will see an example of that in Chapter 10, “Deploying, Securing, and Configuring Windows-Based Applications.”

Setting Security Account Context for Windows Services

A Windows service runs independently of any user who might be logged onto the computer; therefore, the service must have a security identity of its own. When you create a Windows service application, you can select from one of four options for the security identity:

User  You create a specific username and password (using the standard Windows tools for doing so) for your application. Provide this username and password during installation. You must also provide this user with the appropriate permissions to complete the work of the Windows service application.

LocalSystem  LocalSystem is a built-in Windows account. It is the most commonly used setting for Windows services. It is a highly privileged account and is seen by other servers as an anonymous account.

LocalService  This is a built-in Windows account. It provides limited privileges on the local computer and is seen by other computers on the network as an anonymous user, so it is unlikely that code running under this identity will be allowed access to resources on other computers on the network. This account is available only on Windows XP and later operating systems.

NetworkService  This is a built-in Windows account. It runs with limited privileges on the local computer and can communicate with other servers as an authenticated domain account. This account is available only on Windows XP and later operating systems.

Again, the most commonly used security identity is LocalSystem. This built-in Windows account has a high level of privileges on the computer system. However, it is considered good security practice for applications to run with the least privileges required to perform their work. For example, do not allow the privilege to write to the system Registry if that is not needed to perform the core function of the service. To provide stronger security options, Windows XP and later operating systems have two new built-in accounts: LocalService and NetworkService. These two accounts have fewer privileges assigned to them by default. When installing a Windows service application, you should determine the level of privilege required and choose the best account.

Note 

These security accounts and other security considerations are discussed more thoroughly in Chapter 10.

Running a Windows Service

Unlike most .NET projects, you cannot run a Windows service application directly from the Visual Studio .NET IDE by choosing Debug Ø Start from the main menu (or its equivalent toolbar or keystroke shortcuts). If you try to do this, you will see a message box that reads:

“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.”

What this means is that you cannot interactively run your application for testing from within the Visual Studio .NET IDE. That is the way most Visual Basic .NET developers are used to working, and it’s very convenient. Working with Windows service applications is a bit more structured.

You must first build and install your Windows service before you can test and debug it to see whether it is working correctly. Although this seems like a big drawback to developing this type of application, keep in mind that a Windows service application runs in a different context than regular user applications. It runs in the context of the Service Control Manager and under a different security context than the user identity that you are logged in as during development. To debug a Windows service application, you must complete the application, install it, and then attach a debugger to the running process.

We cover the steps to attaching a debugger to the process later in this chapter, in the section “Debugging a Windows Service.” In Exercise 1.2, you will create a simple Windows service application. The steps for creating a setup project that will perform the installation of the service are included in the exercise. For a full explanation of creating setup and deployment projects, see Chapter 10.

Tip 

For practical purposes, in real-world Windows service applications, you will probably want to create a Console or Windows Forms application to interactively test specific program logic before you add the code to your Windows service. After you are satisfied that your test code is working correctly, you can add it to the methods of your Windows service project.

For your first Windows service, you are going to design a simple service that uses a custom event log to record information about when the service is started and stopped.

You will create a new Windows service application project called CustomLogService. Next you will change some properties of the component. You will also add EventLog and Installer components from the Toolbox to the project. Finally, you are going to add code to the OnStart and OnStop events and also to the constructor method, Sub New.

Exercise 1.2: Creating a Windows Service by Using Visual Studio .NET

start example

Setting Up the Project:

  1. Start Visual Studio .NET and create a new project by using the Windows Service project template. Name the project CustomLogService and select an appropriate directory on your computer.

  2. Using the Solution Explorer, rename the component Service1.vb to CustomLogService.vb.

  3. Click on the design surface of CustomLogService.vb and display the Properties window. Change both the Name property and the Service name property to CustomLogService. Change the AutoLog property to False. Change the CanStop property to True.

    click to expand

  4. Display the Visual Studio .NET Toolbox and click the Components tab. Drag an EventLog component onto the design surface.

  5. Click the EventLog component and display the Properties window. Change the name to CustomEventLog.

    Adding Code:

  6. Open the code editor for CustomLogService.vb. Verify that the class is named CustomLogService and that it inherits from System.ServiceProcess.ServiceBase:

    Public Class CustomLogService     Inherits System.ServiceProcess.ServiceBase
  7. Expand the region titled Component Designer Generated Code. Add code to the New procedure. Code to initialize the custom event log is placed in the New procedure, instead of OnStart, because you want this code to run only when the Windows service is first installed, rather than each time it is restarted. Your completed code should look like this:

       Public Sub New()         MyBase.New()         ' This call is required by the Component Designer.         InitializeComponent()         ' Add any initialization after InitializeComponent()         If Not EventLog.SourceExists("CustomSource") Then             EventLog.CreateEventSource("CustomSource", "CustomLog")         End If         CustomEventLog.Source = "CustomSource"         CustomEventLog.Log = "CustomLog"    End Sub 

  8. Add code to the OnStart and OnStop event procedures. Here you will write an entry to the custom event log to keep track of when the service is stopped and started. Your code should look like this:

       Protected Overrides Sub OnStart(ByVal args() As String)         CustomEventLog.WriteEntry("The service has been started.")    End Sub    Protected Overrides Sub OnStop()        CustomEventLog.WriteEntry("The service has been stopped.")    End Sub

    Adding Installer Components:

  9. Click the design surface of CustomLogService.vb and display the Properties window. Near the bottom of the Properties window is a link titled Add Installer. Click this link, and a new component class module called ProjectInstaller.vb will be added to your project. You will see the design surface for this component has two other component icons on it: ServiceProcessInstaller1 and ServiceInstaller1.

    click to expand

  10. Click ServiceProcessInstaller1 and display the Properties window. Select the Account property. Choose LocalSystem from the drop-down list. (If you decide to have your service running under a user account, you would also fill in the necessary information in the Password and Username properties here.)

  11. Click ServiceInstaller1 and display the Properties window. Select the StartType property. Choose Automatic from the drop-down list.

    Building the Service:

    Before you can build the service, you need to clean up some details.

  12. Display the Task List window by choosing View Ø Other Windows Ø Task List from the menu. You will most likely see two errors; the first one says “Type Service1 is not defined.” There is a remaining reference to the default name Service1.

  13. Double-click this entry in the Task List window, the code editor window will display the section of code where the error is located and the line of code that is in error will be highlighted. Change Service1 to CustomLogService.

  14. The next item in the Task List says “’Sub Main’ was not found in ‘CustomLogService.Service1’”. This refers to the project Startup Object. Double-click this entry in the Task List window, and a dialog box pops up showing the new correct reference to CustomLogService.CustomLogService. Select this item and click OK.

  15. Now you can build the CustomLogService. Right-click the project name in the Solution Explorer and choose Build, or choose Build Ø Build CustomLogService from the menu.

  16. Save the CustomLogService project. You will be using it for future exercises.

    Creating a Setup Project to Install the Service:

    Many details are involved in creating a setup project and deploying Windows service applications. This topic is covered in more detail in Chapter 10. The following instructions are designed to get your new application up and running quickly so you can test it.

  17. In the Solution Explorer, click on the solution. Choose File Ø Add Project Ø New Project from the Visual Studio menu.

  18. In the Add New Project dialog box, select Setup and Deployment Projects and select the Setup Project template. Name the new project CustomLogSetup. Click OK.

  19. In the Solution Explorer, right-click CustomLogSetup. Choose Add Ø Project Output from the menu. The Add Project Output Group dialog box displays. Select Primary Output and click OK.

  20. In the Solution Explorer, right-click CustomLogSetup again. Choose View Ø Custom Actions from the menu.

  21. In the upper-left corner of the work area, right-click Custom Actions. Choose Add Custom Action. The Select Item in Project dialog box displays. Double-click Application Folder, select Primary Output from CustomLogService (Active), and click OK. Your screen should look like the following one.

    click to expand

  22. Build the setup project. Right-click the project name in the Solution Explorer and choose Build, or choose the menu command Build Ø Build CustomLogSetup.

  23. Save the CustomLogSetup project, because you will be using it again later in this chapter.

    Installing and Testing the Service:

  24. In the Debug subdirectory of the CustomLogSetup project directory, you will find a Windows Installer file named CustomLogSetup.msi. Double-click this file to start the installation.

  25. This will start a Setup Wizard. Accept all the defaults and complete the installation.

  26. Run the Service Control Manager to verify that your service is installed. To do this, click Start Ø Programs Ø Administrative Tools Ø Services (or the appropriate sequence for your operating system version). You should see CustomLogService in the list.

  27. Right-click on your service and choose Properties. Start your service.

  28. Click Start Ø Programs Ø Administrative Tools Ø Event Viewer (or the appropriate sequence for your operating system version) to view your custom event log in the Event Viewer.

    click to expand

  29. Click the log named CustomLog.Then right-click any one of the log entries and choose Properties (or just double-click the entry). You will see your custom message in the Properties dialog box.

    click to expand

end example



MCAD/MCSD(c) Visual Basic. NET XML Web Services and Server Components Study Guide
MCAD/MCSD: Visual Basic .NET XML Web Services and Server Components Study Guide
ISBN: 0782141935
EAN: 2147483647
Year: 2005
Pages: 153

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