Click here to Skip to main content
Click here to Skip to main content

Using .NET 2.0 to Create a Windows Service

, 30 Mar 2008 CPOL
Rate this:
Please Sign up or sign in to vote.
This article describes Windows Services and their creation.

Introduction

The .NET Framework is said to run atop of the Windows Operating System, despite the fact it is a system program. At the highest level, it performs type-safety checks, code access security, lays out objects in memory, activates those objects, executes, and then destroys them. But, almost every Operating System has a mechanism to start processes at system startup time that provides services not tied to an interactive user. Such processes are called Windows Service applications, as they start automatically when the Operating System boots. An example of a Windows Service would be a web browser because it must be running regardless of whether anyone is logged onto the computer, and it must start running when the system starts. I am writing this paper to explain how to create a Windows Service using .NET Framework 2.0 along with Visual Studio 2005. The reason these services are called Windows Services is because they rely on the Windows API to interact with the system. Before explaining how to use managed code to build service components, I will explain the basic architectural model of Windows Services.

Windows Services consist of three main components: a service application, a Service Control Program (SCP), and the Service Control Manager (SCM). The service program itself provides the actual functionality that you are looking for. A user who wants to start, stop, or configure a service uses an SCP. With a service control program, it is possible to send control requests to a service, namely start, stop, pause, or continue. Stated loosely, a service application program is basically a Windows executable with additional code to receive commands from the SCM as well as to communicate the application's status back to the SCM. When you install an application that includes a service, the application's setup program must register the service with the system. To register this service, the setup program calls the Windows CreateService function, a services-related function implemented in Advapi32.dll (the Advanced API DLL). The Advapi32.dll implements all client-side SCM APIs. When the setup program calls the CreateService function, a message is sent to the SCM, which, in turn, creates a Registry key for the service under HKLM\SYSTEM\CurrentControlSet\Services. The individual keys for each service define the path of the executable image that contains the service.

In the .NET Framework, service classes are within the System.ServiceProcess namespace that implements the three parts of a service: you have to inherit from the ServiceBase class to implement a service. The ServiceBase class is used to register the service and to answer start and stop requests. The ServiceController class is used to implement a service control program. With this class, you send requests to services. The ServiceProcessInstaller and ServiceInstaller classes are classes to install and configure your service programs.

Creating a Windows Service

We are going to fire up Visual Studio 2005 and make use of those partial classes supported by the .NET Framework 2.0 and C# 2.0. We want to create a small Windows application that uses the ServiceController class to monitor and control services. You simply create a Windows Forms application with a user-interface that will contain a list box to show all of the services, and text boxes to display the name, status, and type of a service. We also add four button controls to send control events. Because the class System.ServiceProcess.ServiceController is used, you must reference the assembly System.ServiceProcess (System.ServiceProcess.dll).

#region Using directives
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.ServiceProcess;
#endregion
namespace ServiceControl
{

partial class ServiceControlForm : Form
{
    private System.ServiceProcess.ServiceController[] services;
    public ServiceControlForm()
    {
        InitializeComponent();
        RefreshServiceList();
    }
    private void RefreshServiceList()
    {
        services = ServiceController.GetServices();
        listBoxServices.DisplayMember = "DisplayName";
        listBoxServices.DataSource = services;
    }

Notice that we create the RefreshServiceList method to list all of the services in the ListBox. This method is called within the constructor of the class ServiceControlForm. The method's implementation is to fill a ListBox control with the display names of all the services. It is important to note that the GetServices() method is a static method of the ServiceController class, and it returns a ServiceController array representing all Windows Services. Collections start where arrays leave off. The ListBox is filled by binding ServiceController.GetServices() to the ListBox.

The code shown below controls the services. Notice that the code for starting, stopping, pausing, and suspending are similar, only needing one handler for the four buttons:

protected void buttonCommand_Click(object sender, System.EventArgs e)
{
    Cursor.Current = Cursors.WaitCursor;
    ServiceController controller =
         (ServiceController)listBoxServices.SelectedItem;
    if (sender == this.buttonStart)
    {
        controller.Start();
        controller.WaitForStatus(ServiceControllerStatus.Running);
    }
    else if (sender == this.buttonStop)
    {
        controller.Stop();
        controller.WaitForStatus(ServiceControllerStatus.Stopped);
    }
    else if (sender == this.buttonPause)
    {
        controller.Pause();
        controller.WaitForStatus(ServiceControllerStatus.Paused);
    }
    else if (sender == this.buttonContinue)
    {
        controller.Continue();
        controller.WaitForStatus(ServiceControllerStatus.Running);
    }
    int index = listBoxServices.SelectedIndex;
    RefreshServiceList();
    listBoxServices.SelectedIndex = index;
    Cursor.Current = Cursors.Default;
}

protected void buttonExit_Click(object sender, System.EventArgs e)
{
    Application.Exit();
}

protected void buttonRefresh_Click(object sender, System.EventArgs e)
{
    RefreshServiceList();
}

Download the code and build the solution. Try running without starting the debugging process. Well, that is all for now. Suggestions or pointers are welcome.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

logicchild
Other Pref. Trust
United States United States
I started electronics training at age 33. I began studying microprocessor technology in an RF communications oriented program. I am 43 years old now. I have studied C code, opcode (mainly x86 and AT+T) for around 3 years in order to learn how to recognize viral code and the use of procedural languages. I am currently learning C# and the other virtual runtime system languages. I guess I started with the egg rather than the chicken. My past work would indicate that my primary strength is in applied mathematics.

Comments and Discussions

 
QuestionWhere's the beef? PinmemberPIEBALDconsult31-Mar-08 11:21 
AnswerRe: Where's the beef? Pinmemberhdolder17-Sep-08 5:19 
GeneralRe: Where's the beef? PinmemberPIEBALDconsult17-Sep-08 8:22 
GeneralRe: Where's the beef? Pinprofessional@AmitGajjar28-Jan-14 19:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.141022.2 | Last Updated 30 Mar 2008
Article Copyright 2008 by logicchild
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid