Click here to Skip to main content
15,885,767 members
Articles / Desktop Programming / Win32
Tip/Trick

How to Control a Windows Service from Code

Rate me:
Please Sign up or sign in to vote.
4.87/5 (14 votes)
28 Dec 2013CPOL1 min read 57.9K   2.4K   27   11
How to control a Windows Service from C# .NET

Introduction

This simple example shows how you can control a Windows Service from C# code. In this example, we are going to do the following tasks on the spooler (print) service:

  • Check if it is disabled
  • Check if it is enabled
  • Stop the service
  • Start the service
The .NET Framework is already equipped with a class called ServiceController to control Windows services. With this class, you can start, stop, pause, restart and get the status from a Windows Service.

Since it is not possible to check if a Windows Service is enabled or disabled with the ServiceController class and to wrap everything up, I created a class with all the code inside. This class is called Windo<code>wsServiceMonitor. The class is extended with a few functions like:
  • Disable (to disable the Windows Service)
  • Enable (to enable the Windows Service
  • IsDisabled (to check if the Windows Service is disabled)
To get these 3 functions to work, we use the ManagementObjectSearcher and the Registry class.

Using the Code

To test the WindowsServiceMonitor class, we create a simple Winform application as shown below:

Image 1

From this form, we use the WindowsServiceMonitor class. Before we can use this class, we need to create it. In the form application, this is done in the Form load event.
C#
private void MainForm_Load(object sender, EventArgs e)
{
     _windowsServiceMonitor = new WindowsServiceMonitor(ServiceTextBox.Text);
}
To start the spooler, we call the Start() function:

C#
_windowsServiceMonitor.Start();

To stop the spooler, we call the Stop() function:

C#
_windowsServiceMonitor.Stop();

To disable the spooler, we call the Disable() function:

C#
_windowsServiceMonitor.Disable(); 

To enable the spooler, we call the Enable() function:

C#
_windowsServiceMonitor.Enable();

All this is done through our WindowsServiceMonitor class:

C#
using System;
using System.Linq;
using System.Management;
using System.ServiceProcess;
using Microsoft.Win32;

namespace ServiceController
{
    /// <summary>
    /// This class can be used to monitor a windows service
    /// </summary>
    public class WindowsServiceMonitor
    {
        #region Fields
        /// <summary>
        /// The Windows service that is controlled through the .NET ServiceController
        /// </summary>
        private readonly System.ServiceProcess.ServiceController _service;
        #endregion

        #region Properties
        /// <summary>
        /// Name of the Windows service
        /// </summary>
        public string ServiceName { get; private set; }

        /// <summary>
        /// Tells us if the Windows service is running
        /// </summary>
        public bool IsRunning
        {
            get { return _service.Status == ServiceControllerStatus.Running; }
        }
        
        /// <summary>
        /// Tells us if the Windows service is stopped
        /// </summary>
        public bool IsStopped
        {
            get { return _service.Status == ServiceControllerStatus.Stopped; }
        }

        /// <summary>
        /// Tells us if the Windows Service is disabled
        /// </summary>
        public bool IsDisabled
        {
            get
            {
                try
                {
                    var query = String.Format("SELECT * 
                    FROM Win32_Service WHERE Name = '{0}'", _service.ServiceName);
                    var querySearch = new ManagementObjectSearcher(query);

                    var services = querySearch.Get();

                    // Since we have set the servicename in the constructor we asume the first result is always
                    // the service we are looking for
                    foreach (var service in services.Cast<managementobject>())
                        return Convert.ToString(service.GetPropertyValue
                        ("StartMode")) == "Disabled";
                }
                catch
                {
                    return false;
                }

                return false;
            }
        }

        /// <summary>
        /// Can be called to enable the Windows Service
        /// </summary>
        public void Enable()
        {
            try
            {
                var key = Registry.LocalMachine.OpenSubKey
                (@"SYSTEM\CurrentControlSet\Services\" + ServiceName, true);
                if (key != null) key.SetValue("Start", 2);
            }
            catch (Exception e)
            {
                throw new Exception("Could not enable the service, error: " + e.Message);
            }
        }

        /// <summary>
        /// Disables the Windows service
        /// </summary>
        public void Disable()
        {
            try
            {
                var key = Registry.LocalMachine.OpenSubKey
                (@"SYSTEM\CurrentControlSet\Services\" + ServiceName, true);
                if (key != null) key.SetValue("Start", 4);
            }
            catch(Exception e)
            {
                throw new Exception("Could not disable the service, error: " + e.Message);
            }
        }

        /// <summary>
        /// This will give us the displayname for the 
        /// Windows Service that we have set in the constructor
        /// </summary>
        public string DisplayName
        {
            get { return _service.DisplayName; }
        }
        #endregion

        #region Constructor
        /// <summary>
        /// Create this class for the given service.
        /// </summary>
        /// <param name="serviceName" />
        /// The name of the service (don't use the display name!!)
        public WindowsServiceMonitor(string serviceName)
        {
            _service = new System.ServiceProcess.ServiceController(serviceName);
            ServiceName = _service.ServiceName;
        }
        #endregion

        #region Start
        /// <summary>
        /// Start the Windows service, a timeout exception will be thrown when the service
        /// does not start in one minute.
        /// </summary>
        public void Start()
        {
            if (_service.Status != ServiceControllerStatus.Running || 
            _service.Status != ServiceControllerStatus.StartPending)
                _service.Start();

            _service.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 1, 0));
        }
        #endregion

        #region Stop
        /// <summary>
        /// Stop the Windows service, a timeout exception will be thrown when the service
        /// does not start in one minute.
        /// </summary>
        public void Stop()
        {
            _service.Stop();
            _service.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 1, 0));
        }
        #endregion

        #region Restart
        /// <summary>
        /// Restart the Windows service, a timeout exception will be thrown when the service
        /// does not stop or start in one minute.
        /// </summary>
        public void Restart()
        {
            Stop();
            Start();
        }
        #endregion
    }
}

History

  • First version

License

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


Written By
Software Developer (Senior)
Netherlands Netherlands
Programming since I was a kid. Started on the Commodore 64 with BASIC. Since then I used programming languages like Turbo Pascal, Delphi, C++ and Visual Basic 6.

Now a days I do a lot of programming in C# with underlying databases like MS SQL

Comments and Discussions

 
QuestionEvent - Service Stopped, Paused Pin
stixoffire14-May-15 6:28
stixoffire14-May-15 6:28 
AnswerRe: Event - Service Stopped, Paused Pin
Kees van Spelde14-May-15 8:22
professionalKees van Spelde14-May-15 8:22 
BugNot Working Properly. Pin
SandeepKushwah29-Mar-15 22:22
SandeepKushwah29-Mar-15 22:22 
GeneralRe: Not Working Properly. Pin
Kees van Spelde31-Mar-15 6:37
professionalKees van Spelde31-Mar-15 6:37 
QuestionHow to Send and receive the Dataset From Window Service Pin
Maria Norbert21-May-14 20:28
Maria Norbert21-May-14 20:28 
AnswerRe: How to Send and receive the Dataset From Window Service Pin
Kees van Spelde22-May-14 4:16
professionalKees van Spelde22-May-14 4:16 
GeneralMy vote of 5 Pin
johannesnestler9-Jan-14 3:44
johannesnestler9-Jan-14 3:44 
QuestionAbout more practical situations Pin
wmjordan28-Dec-13 18:18
professionalwmjordan28-Dec-13 18:18 
Controlling the service is easy with .NET platform.
However, when we work with a service, we may probably want to know what the service is doing when we are going to terminate it.
For example, we may have a broker service which sends data and commands to somewhere else on the network. If we are going to stop it, a better approach is to tell the service "Hey, you are going to take a rest. Please finish your job." And then the service will get a chance to know what's happening, and it may strive to finish the pending task and refuse upcoming ones, at the same time, the service shall request more time from the services host, and if possible, the service tells the controller program then the controller pops up a feedback dialog window showing how many jobs are in the queue with a "Terminate right now" button which may unconditionally ends the service when it is clicked by the user.
If this pattern is not applied, the task may be ended with some jobs unfinished and lead to undesirable results.
AnswerRe: About more practical situations Pin
mav.northwind28-Dec-13 21:39
mav.northwind28-Dec-13 21:39 
GeneralRe: About more practical situations Pin
Kees van Spelde29-Dec-13 1:59
professionalKees van Spelde29-Dec-13 1:59 
AnswerRe: About more practical situations Pin
johannesnestler9-Jan-14 3:43
johannesnestler9-Jan-14 3:43 

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

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