Methods to Help Working with Services






4.93/5 (8 votes)
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