Apply Your Knowledge



Apply Your Knowledge

Exercises

Passing Startup Parameters to a Windows Service

When you start a Windows service, you can also pass startup parameters to the service.

In this exercise, I'll create a new Windows service named OrderServiceEx. This Windows service is almost same as OrderService, which was created in Step-by-Step 6.1. The only difference is that OrderServiceEx accepts the value of the NotifyFilter property and the Path property of the FileSystemWatcher component at the time of starting the Windows service.

The startup parameters to a Windows service are given the same way as command-line arguments are provided to a console application. However, the only difference is that rather than accepting the arguments in the Main() method, the Windows services accepts arguments in the OnStart() method. The Main() method here is common to several Windows services in an application. However, each of these services has its own individual OnStart() method.

Estimated Time: 30 minutes.

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

  2. Add a new C# Windows Service project named Exercise6_1 to the solution.

  3. The Windows service project contains a file named Service1.cs. Rename this file to OrderServiceEx.cs. Click on the designer surface; then in the Properties windows, set the Name and ServiceName properties to OrderServiceEx, and set the CanPauseAndContinue property to true.

  4. Switch to the code view and change all occurrences of Service1 to OrderServiceEx. Add the following using directives to the code:

    
    using System.Data.SqlClient;
    
    using System.IO;
    
    
  5. Add a FileSystemWatcher component onto the surface of the OrderServiceEx component. Access the Properties window for the FileSystemWatcher component and change its Name property to fswOrders and its EnableRaisingEvent property to false.

  6. Click on the Events icon on the Properties window and double-click on the Created event to attach an event handler. Add the following code to the event handler:

    
    private void fswOrders_Created(
    
         object sender,
    
         System.IO.FileSystemEventArgs e)
    
    {
    
        DataSet dsOrders =
    
           new DataSet("Orders");
    
        // Read the contents of the XML file
    
        // into the Orders DataSet
    
        dsOrders.ReadXml(e.FullPath);
    
    
    
       // Set up the database connection string
    
        string strConn =
    
            "data source=(local);" +
    
            "initial catalog=Northwind;" +
    
            "integrated security=SSPI";
    
        string strOrderQuery =
    
            "Select * from orders";
    
        // Create a DataAdapter for the Orders
    
        // table of the Northwind database
    
        SqlDataAdapter daOrders =
    
            new SqlDataAdapter(
    
             strOrderQuery, strConn);
    
        // Automatically generate the update
    
        // command to reconcile the changes
    
        // made to the DataSet
    
        SqlCommandBuilder cbOrders =
    
            new SqlCommandBuilder(daOrders);
    
        //Update the DataSet
    
        daOrders.Update(dsOrders, "Orders");
    
        daOrders.Dispose();
    
        FileInfo fi = new FileInfo(e.FullPath);
    
       // Create a subdirectory named "Updated"
    
        // if it does not already exist
    
        fi.Directory.CreateSubdirectory(
    
            "Updated");
    
        // Copy the processed XML file
    
        // to the 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();
    
    }
    
    
  7. In the code, search for the skeletons of the OnStart() and OnStop() methods and modify them as follows:

    
    protected override void OnStart(
    
        string[] args)
    
    {
    
        fswOrders.Filter = args[0];
    
        fswOrders.Path = args[1];
    
        fswOrders.EnableRaisingEvents = true;
    
    }
    
    
    
    protected override void OnStop()
    
    {
    
        fswOrders.EnableRaisingEvents = false;
    
    }
    
    
  8. Add the following code to the OrderService class to override the OnPause() and the OnContinue() methods of the base class:

    
    protected override void OnPause()
    
    {
    
        fswOrders.EnableRaisingEvents = false;
    
    }
    
    
    
    protected override void OnContinue()
    
    {
    
        fswOrders.EnableRaisingEvents = true;
    
    }
    
    
  9. Access the Properties window for the OrderServiceEx component and click on the Add Installer hyperlink.

  10. Access the properties for the serviceProcessInstaller1 component and change its Account property from User to LocalSystem.

  11. Access the properties for the serviceInstaller1 component, and change its ServiceName properties to OrderServiceEx and its StartType property to Automatic.

  12. Build the project StepByStep6_1. Open the Visual Studio .NET command prompt, switch to the bin\debug directory of the project and type the following command:

    
    installutil.exe StepByStep6_1.exe
    
    
  13. Open the Services MMC snap-in. Open the property window for OrderServiceEx. In the Start parameters text box type the following as shown in Figure and click on the Start button:

    
    *.xml c:\ordersEx
    
    
    14. You can specify start parameters for a Windows service.

    graphics/06fig14.jpg

  14. Create an XML file in the c:\OrdersEx folder. You may use the same XML file used in Step-by-Step 6.4. You'll note that the record has been updated to the Orders table in the Northwind database.

Review Questions

1:

What is a Windows service?

A1:

A Windows service is a long-running process that usually runs in the background without any user interaction. A Windows service must conform to the interface provided by the Windows Service Control Manager.

2:

What is the Service Control Manager (SCM) and what does it do?

A2:

The Service Control Manager (SCM) is a part of the operating system that manages Windows services. SCM also manages the Windows service database (which is stored in the Windows Registry) and provides a mechanism through which other programs can interact with the Windows service database and the Windows services in execution.

3:

How can you control and monitor a Windows service?

A3:

You can control and monitor a Windows service in several ways. The easiest is to use the tools that come installed with Windows, such as the NET utility (net.exe), Service Control utility (sc.exe), and the Services MMC snap-in. You can also control Windows services through the Server Explorer of Visual Studio .NET. Sometimes you may need to control the Windows service programmatically; in that case, you can use the methods and properties of the ServiceController class.

4:

What is the significance of the Run() method of the ServiceBase class?

A4:

The Run() method is usually called from the Main() method of a Windows service executable file. The Run() method loads an application's Windows services in memory and passes references to the Windows service objects to the SCM. This enables the SCM to pass control messages to a Windows service.

5:

How can you programmatically enumerate the Windows services installed on a computer?

A5:

You can get a list of the Windows services installed on a computer by calling the static ServiceController.GetServices() method. This method returns an array of ServiceController objects, each associated with a Windows service.

6:

How do you write to an event log from a Windows service application?

A6:

To write entries in the Application event log from a Windows service application, you just need to use the EventLog.WriteEntry() method. However, if you need to write entries to any other event log, you should create a new EventLog object in your application.

7:

How can you receive startup parameters in a Windows service?

A7:

Any startup parameters provided to a Windows service are passed to the OnStart() method call as an array of strings. You can process this array to retrieve the startup parameters in the OnStart() method.

8:

What is the difference between the ServiceProcessInstaller and the ServiceInstaller classes?

A8:

The ServiceProcessInstaller class performs the installation tasks that are common to all Windows services in an application. These include setting the logon account for the Windows service. The ServiceInstaller class, on the other hand, performs the installation tasks that are specific to a Windows service, such as setting the ServiceName and StartType.

Exam Questions

1:

You are required to design an application that monitors incoming emails and analyzes them to filter out junk emails. The emails arrive at a well-known port and you use conditions stored in an XML file to determine whether an email is possibly a junk email. Your application bounces back all junk email while forwarding the other emails to a groupware application. You want this application to run continuously with minimal interaction with the desktop user. How should you design this application?

  1. Design the application as a Windows forms application

  2. Design the application as a Windows service application

  3. Design the application as a Web forms application

  4. Design the application as a Web service application

A1:

B. The application in question runs continuously and requires minimal user interaction. The application also just listens to email and is not required to listen to Web-based requests. Given these characteristics, you should design this application as a Windows service rather than any of the application types specified in the other options. For more information, see the section "Understanding Windows Services" in this chapter.

2:

You are designing a Windows service application that will be used by other applications over the Internet. You want the users of the application to have access to only certain directories on your system. Which of the following techniques should you use?

  1. When installing the Windows service, set the Account property to User. Also, specify the username and password for an account that has access to only the required directories.

  2. When starting the Windows service, set the Account property to User. Also, specify the username and password for an account that has access to only the required directories.

  3. When installing the Windows service, set the Account property to NetworkService. Also specify the username and password for an account that has access to only the required directories.

  4. When starting the Windows service, set the Account property to NetworkService. Also, specify the username and password for an account that has access to only the required directories.

A2:

A. You can specify the security settings for a Windows service only at the time of installation. When you want to run the Windows service with a specific username and password, the Account property must be set to User. For more information, see the sections "Architecture of Windows Services" and "Installing a Windows Service" in this chapter.

3:

You are working on a team that is designing a Windows service that monitors Web server performance on an ongoing basis. You are given a task to make sure that an entry is written to the Application event log when the Windows service is started, paused, resumed, or stopped. You want to write a minimum amount of code to achieve this. Which of the following options would you choose?

  1. Use the EventLog property of the Windows service class to write entries to the application log.

  2. Set the AutoLog property of the Windows service class to true.

  3. Create an EventLog component in the project and use this component to write entries in the event log.

  4. Create a method that writes entries in the event log and call this method from OnStart(), OnStop(), OnPause(), and OnContinue() methods of the Windows service class.

A3:

B. When you set the AutoLog property to true, the Windows service class automatically writes events to the Application event log. All other options require more code to be written to achieve the same results. For more information, see the section "The System.ServiceProcess.ServiceBase Class" in this chapter.

4:

You are developing a Windows service application that accepts startup parameters. Which of the following methods would you program to retrieve and process these parameters?

  1. The Main() method

  2. The Run() method

  3. The OnStart() method

  4. The constructor of the Windows service class

A4:

C. When a Windows service is started, any startup parameters are passed to the OnStart() method. For more information, see the section "The System.ServiceProcess.ServiceBase Class" in this chapter.

5:

You are part of a team that is developing a Windows service application to monitor a legacy application for new data. Occasionally your application may encounter errors. You want to develop an error reporting mechanism that is easy to use for administrators who will monitor and maintain the application on day-to-day basis. You also want a scheme that is robust and requires a minimum amount of code. Which of the following techniques should you choose?

  1. Event Log.

  2. SQL Server tables.

  3. XML-based log files.

  4. Plain-text log files.

A5:

A. You should use the event log for error reporting from a Windows service. Event logs are easy to use for administrators because they already use event logs for monitoring notifications from other applications. The service base class provides an EventLog property that allows you to use a single line of code to write messages to the Application event log. For more information, see the section "The System.ServiceProcess.ServiceBase Class" in this chapter.

6:

You have designed a Windows service application that contains two Windows services. You now want to add installer classes to this application so that the application can be installed with tools such as installutil.exe. You have added a new class inherited from the Installer class in your application. To the Installers collection of this class, you would like to add the custom installation components for properly installing the Windows services in your application. Which of the following combinations of custom components would you like to add to the Installers collection of the Installer class?

  1. Add two instances of the ServiceProcessInstaller class and one instance of the ServiceInstaller class.

  2. Add two instances of the ServiceInstaller class and one instance of the ServiceProcessInstaller class.

  3. Add two instances each of the ServiceInstaller class and the ServiceProcessInstaller classes.

  4. Add one instance each of the ServiceInstaller class and the ServiceProcessInstaller classes.

A6:

B. For installing a Windows service application, you need to have one instance of the ServiceProcessInstaller class and as many instances of the ServiceInstaller class as the number of services you want to install. For more information, see the section "The ServiceProcessInstaller and the ServiceInstaller Classes" in this chapter.

7:

You are required to design a Windows service that cannot be paused. Which of the following options will help you to accomplish this requirement?

  1. Set the CanStart property of the Windows service to true, but set the CanStop property to false.

  2. Set the CanPauseAndContinue property of the Windows service to false.

  3. Do not include definitions for the OnPause() and OnContinue() methods in the class definition of the Windows service.

  4. Do not include a definition for the OnStop() method in the class definition for Windows service.

A7:

B. If you do not want a Windows service to be paused, you need to set the CanPauseAndContinue property of the Web service to false. If this property is true, the SCM may send pause and continue messages to your service. The CanStop property and the OnStop() method won't help because stopping a Windows service is different from pausing a Windows service. In case of stopping, the Windows service is unloaded from memory and all its resources are reclaimed. For more information, see the section "Creating a Windows Service Application" in this chapter.

8:

Your application is required to monitor changes to files in the c:\Documents directory. You are especially interested in taking actions when there are any changes to the PDF files in this directory. You are using a FileSystemWatcher component to accomplish this task. How should you set the Filter and NotifyFilter properties of this component? (Select two.)

  1. Set the Filter property to "*.pdf".

  2. Set the NotifyFilter property to LastWrite.

  3. Set the NotifyFilter property to "*.pdf".

  4. Set the Filter property to LastWrite.

A8:

A and B. For a FileSystemWatcher component, the Filter property specifies what files are to be monitored, whereas the NotifyFilter specifies the type of changes the application is to watch for. For more information, see the section "Creating the OrderService Application" in this chapter.

9:

You have recently designed a Windows service application. You now want to install the application to test its functionality. Which of the following options should you choose to install this application?

  1. Use the Visual Studio .NET Server Explorer.

  2. Use the Services MMC snap-in.

  3. Use net.exe.

  4. Use installutil.exe.

A9:

D. Although the Server Explorer, Services MMC snap-in, and the .NET utility enable you to control and monitor a Windows service, they do not enable you to install one. To install a Windows service, either you should use installutil.exe or you should create a Windows installer-based setup project. For more information, see the section "Installing a Windows Service" in this chapter.

10:

You are designing an application that needs to know the Windows services that are installed on a computer. Which of the following classes would allow you retrieve this information?

  1. ServiceBase

  2. ServiceInstaller

  3. ServiceController

  4. ServiceProcessInstaller

A10:

C. The ServiceController class interacts with SCM to enumerate the list of services installed on a computer. You get this information by using the static GetServices() method of this class. For more information, see the section "The ServiceController Class" in this chapter.

11:

Your group is designing a Windows service application that constantly monitors the computer to keep it tuned. This service performs tasks such as disk defragmentation, Registry cleanup, and virus detection. The service needs to have high privilege to perform its task. In what security context should you set up this service to run?

  1. LocalService

  2. LocalSystem

  3. NetworkService

  4. User

A11:

B. The LocalSystem value defines a highly privileged account. As compared to this, the LocalService and NetworkService values provide a lower privilege level for the security context. Privileges for a User account depend on the specified username and password. For more information, see the section "The ServiceProcessInstaller and the ServiceInstaller Classes" in this chapter.

12:

Which of the following options correctly identifies the security context in which a Windows service is executed?

  1. In the context of the built-in SYSTEM account

  2. In the context of the currently logged-on user

  3. In the context of the Administrator account

  4. In the context of the account information specified at the time of installation of service

A12:

D. Most Windows services are started before a user logs on and they keep on running across multiple user sessions. Therefore, the functionality of a Windows service cannot depend on the permissions available to the currently logged on user. A Windows service always executes by using an assigned user identity that is specified at the time the Windows service is installed. For more information, see the sections "Understanding Windows Services" and "Installing a Windows Service" in this chapter.

13:

You are designing a Windows service application and you want to set the service to start automatically when the computer is restarted. Which of the following classes would allow you retrieve this information?

  1. ServiceBase

  2. ServiceInstaller

  3. ServiceController

  4. ServiceProcessInstaller

A13:

B. The StartType property of the ServiceInstaller class is used to specify whether a service will be started manually, or will be started automatically when the computer starts, or will not start at all. For more information, see the section "The ServiceProcessInstaller and the ServiceInstaller Classes" in this chapter.

14:

Your colleague has designed a Windows service application by inheriting a class from the ServiceBase class. She is complaining that she is able to compile the program successfully, but when she tries to run the program, she is getting an error. What should you suggest to resolve this problem? (Select two.)

  1. Ask your colleague to start the Windows service by using the Service MMC snap-in.

  2. Ask your colleague to restart the computer.

  3. Ask your colleague to add custom installation components in the Windows service application and install the application by using installutil.exe.

  4. Ask your colleague to modify the Windows Registry by using regedit.exe and write the Windows service details there.

A14:

A and C. The Windows service must be installed in the Windows Registry before it can be started. Although the service is installed in the Windows Registry, it is not a good idea to manipulate the Registry directly. You should instead use installation tools such as installutil.exe that interact with SCM to install a Windows service in the Windows Registry. After the service is installed successfully, you should instruct your colleague to start the Windows service by using the Service MMC snap-in because if the start type of the service is not set up as automatic, the service will not start automatically when the computer restarts. For more information, see the section "Installing a Windows Service" in this chapter.

15:

Your colleagues are testing a Windows service application. They are arguing over the order in which the following constructs are called when a Windows service is started:

  • The Main() method of the Windows service application.

  • The Run() method of the ServiceBase class.

  • The OnStart() method of the Windows service.

Which of the following order should you suggest to them?

  1. Main(), Run(), OnStart()

  2. Main(), OnStart(), Run()

  3. OnStart(), Main(), Run()

  4. Run(), Main(), OnStart()

A15:

A. The Main() method of the application is always the first to execute. The Main() method executes the Run() method of the ServiceBase class, which passes the reference of the Windows service to the SCM. The SCM then invokes the OnStart() method of the Windows service. For more information, see the section "Understanding How the SCM Interacts with a Windows Service" in this chapter.

Suggested Readings and Resources

1. Visual Studio .NET Combined Help Collection

• Windows Service Applications

• Service Application Programming Architecture

• Monitoring Windows Services

• Walkthrough: Creating a Windows Service Application in the Component Designer