Click here to Skip to main content
15,868,016 members
Articles / Programming Languages / C#
Tip/Trick

Methods to Help Working with Services

Rate me:
Please Sign up or sign in to vote.
4.93/5 (8 votes)
13 Jun 2018CPOL 5.9K   11   3
This is a set of methods to help in working with Services on the local machine.

Introduction

I was working on a custom installer for a Windows Service pretty much starting from the beginning. One of the issues I had was the code to determine if service exists, starting, stopping, finding the path, and finding the version. This is just a tip that includes the static methods I used. There are more complete methods, but these methods should do for most of what is encountered.

The Code

This is the class that I used for all of the methods used with Windows Services:

using Microsoft.Win32;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management;
using System.Runtime.InteropServices;
using System.ServiceProcess;

namespace InstallApplication
{
    class ServiceMethods
    {
        public static void InstallService(string strInstallService, bool unistall = false)
        {
            InstallService(strInstallService, null, null, unistall);
        }

        public static void InstallService(string strInstallService, string userName, 
			string password = null, bool unistall = false )
        {
            var executeType = unistall ? "u" : "i";
            var userInfo = userName == null ? string.Empty : 
			string.Format(" \"/username={0}\" \"/password={1}\"", userName, password);
            string strInstallUtilPath = Path.Combine(RuntimeEnvironment.GetRuntimeDirectory(),
			 @"InstallUtil.exe");
            if (!File.Exists(strInstallUtilPath))
                throw new FileNotFoundException(string.Format
			("Install Utility path not found: \"{0}\""));
            if (!File.Exists(strInstallService))
                throw new FileNotFoundException(string.Format(
			"Install Service path not found: \"{0}\""));

            ProcessStartInfo processStartInfo = new ProcessStartInfo(strInstallUtilPath, 
			String.Format("/{1} \"{0}\"{2}", strInstallService, executeType, userInfo));
            processStartInfo.RedirectStandardOutput = true;
            processStartInfo.RedirectStandardError = true;
            processStartInfo.UseShellExecute = false;

            Process process = new Process();
            process.StartInfo = processStartInfo;
            process.Start();
            process.WaitForExit();

            if (process.ExitCode == -1)
                throw new Exception(process.StandardOutput.ReadToEnd());
        }

        public static bool ServiceExists(string serviceName)
        {
            //Avoid exceptions this way
            return ServiceController.GetServices().Any(i => i.ServiceName == serviceName);
        }

        public static void ServiceStart(string serviceName)
        {
            using (ServiceController service = new ServiceController(serviceName))
            {
                try
                {
                    if (service.Status == ServiceControllerStatus.Running) return;
                    service.Start();
                    service.WaitForStatus(ServiceControllerStatus.Running);
                }
                catch (Exception ex)
                {
                    throw new Exception(string.Format("Failed to start the Windows Service {0}", 
			serviceName), ex);
                }
            }
        }

        public static void ServiceStop(string serviceName)
        {
            using (ServiceController service = new ServiceController(serviceName))
            {
                try
                {
                    if (service.Status == ServiceControllerStatus.Stopped) return;
                    service.Stop();
                    service.WaitForStatus(ServiceControllerStatus.Stopped);
                }
                catch (Exception ex)
                {
                    throw new Exception(string.Format("Failed to stop the Windows Service {0}", 
			serviceName), ex);
                }
            }
        }

        public static void ServiceRefresh(string serviceName)
        {
            using (ServiceController service = new ServiceController(serviceName))
            {
                try
                {
                    if (service.Status == ServiceControllerStatus.Running)
                    {
                        service.Stop();
                        service.WaitForStatus(ServiceControllerStatus.Stopped);
                    }

                    service.Start();
                    service.WaitForStatus(ServiceControllerStatus.Running);
                }
                catch (Exception ex)
                {
                    throw new Exception(string.Format("Failed to restart the Windows Service {0}", 
			serviceName), ex);
                }
            }
        }

        public static string ServicePath(string serviceName)
        {
            try
            {
                string registryPath = @"SYSTEM\CurrentControlSet\Services\" + serviceName;
                var key = Registry.LocalMachine.OpenSubKey(registryPath);
                string value = key.GetValue("ImagePath").ToString();
                key.Close();
                return value[0] == '\"' ? value.Substring(1, value.Length - 2) : value;
            }
            catch (Exception ex)
            {
                 throw new Exception(string.Format(
			"Error in attempting to get Registry key for service {0}", serviceName), ex);
            }
        }

        public static FileVersionInfo ServiceVersion(string serviceName)
        {
            return FileVersionInfo.GetVersionInfo(ServicePath(serviceName));
        }
    }
}

History

  • 2018-06-13: Initial version
  • 2018-06-15: Updated Service Install to include optional password and username

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) Clifford Nelson Consulting
United States United States
Has been working as a C# developer on contract for the last several years, including 3 years at Microsoft. Previously worked with Visual Basic and Microsoft Access VBA, and have developed code for Word, Excel and Outlook. Started working with WPF in 2007 when part of the Microsoft WPF team. For the last eight years has been working primarily as a senior WPF/C# and Silverlight/C# developer. Currently working as WPF developer with BioNano Genomics in San Diego, CA redesigning their UI for their camera system. he can be reached at qck1@hotmail.com.

Comments and Discussions

 
QuestionTry topshelf Pin
Sacha Barber14-Jun-18 12:14
Sacha Barber14-Jun-18 12:14 
Makes development of win service very nice

AnswerRe: Try topshelf Pin
sps-itsec4614-Jun-18 22:35
sps-itsec4614-Jun-18 22:35 
PraisePretty piece off code Pin
Alexei Agüero Alba14-Jun-18 7:13
Alexei Agüero Alba14-Jun-18 7:13 

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.