This article presents a Windows utility for interacting with a Windows service during the coding phase for start/stop and install/uninstalling, get status of your Windows service rather than opening Visual Studio command prompt, typing in a long command for install/uninstall. Also demonstrates using a simple Windows Service starting a debug session.
The following shows how to install a service using x86 InstallUtil.exe where the path, in this case, is from the author's machine and would change for you.
C:\Windows\Microsoft.NET\Framework\v
4.0
.
30319
\InstallUtil.exe /i C:\Dotnet_Development\ KarenPayneService\bin\Debug\KarenPayneService.exe
The following shows how to uninstall the service above
\InstallUtil.exe /u C:\Dotnet_Development\ KarenPayneService\bin\Debug\KarenPayneService.exe
public
static
void
CreateManualUninstallBatchFile(
string
pServiceProjectFolder,
pExecutableName)
{
_hasException =
false
;
var frameworkPath =
"C:\\Windows\\Microsoft.NET\\Framework"
var utilVersion =
""
var utilNamne =
"InstallUtil.exe"
var result = Directory.GetFiles(frameworkPath,
"installutil.exe"
, SearchOption.AllDirectories);
try
utilVersion = result
.Select(fileName => fileName.Replace(frameworkPath,
).Replace(utilNamne,
)
.Replace(
"\\", "
").Replace("
v
", "
"))
.LastOrDefault();
var executablePathName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory
.UpperFolder(4), pServiceProjectFolder, pExecutableName);
var uninstallCommand = $
"{frameworkPath}\\v{utilVersion}\\{utilNamne} /uninstall {executablePathName}"
var sb =
new
StringBuilder();
sb.AppendLine(
"@Echo off"
);
"@cls"
sb.AppendLine(uninstallCommand);
"pause"
File.WriteAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
"Uninstall.bat"
),sb.ToString());
}
catch
(Exception e)
true
LastException = e;
Open Task Manager, select the service tab, find your service and check the status. Below we can see the service included with the source code for this article.
This is where this utility comes invaluable as checking the status of a service, starting/stopping and install/uninstall are all handled by simple button clicks along with the service status in the form’s status bar.
Setting up the utility for your service
If there are exceptions thrown they are written to the system events so make sure you have permission to write to events as this code assumes you do as a developer.
Note there is a checkbox at the bottom of the window when checked keeps the utility above all other windows which some developers may prefer so the utility is always available while others may find this unwanted.
Rather than opening Windows Explorer to where the utility executable resides and clicking on it.
Locate where to start debugging in code and place the following code, no breakpoints are required. This code will not execute when setup for release. In the screenshot below the "Install Service" button has been pressed along with checking "Start with install" check box. Note the instance of Visual Studio selected in the solution for the service installer. If you don't select this instance a new instance will start which takes time and is not warranted, The following is where debugging will start.
InstallUtil.exe creates a log which is a text file to examine for issues. Since this utility uses InstallUtil.exe it spans a command prompt where you can see what is going on during an install or uninstall so this coupled with the log file provides useful information.
using
System;
System.Collections.Generic;
System.Linq;
System.ServiceProcess;
namespace
ServiceInstaller.Classes
class
WindowsServices
/// <summary>
/// Stop a Windows service service name
/// </summary>
/// <param name="pServiceName"></param>
/// <remarks>
/// A service does not stop instantly, so WaitForStatus method
/// is used to 'wait' until the service has stopped. If the
/// caller becomes unresponsive then there may be issues with
/// the service stopping outside of code.
/// </remarks>
StopService(
pServiceName)
var sc = ServiceController.GetServices()
.FirstOrDefault(service => service.ServiceName == pServiceName);
if
(sc ==
null
return
(sc.Status == ServiceControllerStatus.Running)
sc.Stop();
sc.WaitForStatus(ServiceControllerStatus.Stopped);
(InvalidOperationException)
// here for debug purposes
/// Start a Windows service by service name
StartService(
sc.ServiceName = pServiceName;
(sc.Status == ServiceControllerStatus.Stopped)
sc.Start();
sc.WaitForStatus(ServiceControllerStatus.Running);
/// Determine if service is currently installed
/// <returns></returns>
bool
IsInstalled(
(sc !=
/// Get basic information on running services
List<ServiceDetails> ServiceNames()
var detailList =
List<ServiceDetails>();
var services = ServiceController.GetServices()
.OrderBy(x => x.DisplayName).ToList();
foreach
(var item
in
services)
detailList.Add(
ServiceDetails()
DisplayName = item.DisplayName,
ServiceName = item.ServiceName,
Status = item.Status
});
detailList;
/// provides the service status by string
/// Example usage, set the text of a text box
/// in a form statusbar.
Status(
var status =
"Not installed"
// Get our service, if not found in GetServices then it's not installed
status;
switch
(sc.Status)
case
ServiceControllerStatus.Running:
status =
"Running"
break
ServiceControllerStatus.Stopped:
"Stopped"
ServiceControllerStatus.Paused:
"Paused"
ServiceControllerStatus.StopPending:
"Stopping"
ServiceControllerStatus.StartPending:
"Starting"
default
:
"Status Changing"
System.Diagnostics;
System.IO;
System.Runtime.InteropServices;
System.Windows.Forms;
/// A generic window service installer for install or uninstalling.
Serviceinstaller
/// Location of .NET Framework main folder
FrameWorkDirectory => RuntimeEnvironment.GetRuntimeDirectory();
/// Windows Service installer executable
InstallerCommand => Path.Combine(FrameWorkDirectory,
private
_CommandExeExists;
CommandExecutableExists {
get
_CommandExeExists; } }
ServiceFolder {
set
; }
/// Executable name of the ACED Notification Service { get; set; }
ServiceExecutableName {
ServiceExecutableExists {
ProceedWithOperations {
/// This is the Service name in the ProjectInstaller class of the window service
/// we are working with, in this case database Service.
///
/// Setup and determine if all is in place e.g.found the service executable, service installer executable
ServiceName {
/// Used to install a service
/// <param name="pExecutableName">Service executable name with extension</param>
/// <param name="pServiceKnownName">Name of the Windows service</param>
/// <param name="pServiceProjectFolder">Visual Studio project folder</param>
Serviceinstaller(
pExecutableName,
pServiceKnownName,
pServiceProjectFolder)
ServiceExecutableName = pExecutableName;
ServiceName = pServiceKnownName;
_CommandExeExists = File.Exists(InstallerCommand);
// assumes building for debug not release
ServiceFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory.UpperFolder(4),
"bin"
,
"Debug"
ServiceExecutableExists = File.Exists(Path.Combine(ServiceFolder, ServiceExecutableName));
ProceedWithOperations = CommandExecutableExists && ServiceExecutableExists;
/// Used to uninstall a service.
UninstallService()
var startInfo =
ProcessStartInfo(InstallerCommand) {WindowStyle = ProcessWindowStyle.Normal};
var ops =
WindowsServices();
var statusStates =
[] {
};
(statusStates.Contains(ops.Status(ServiceName)))
startInfo.Arguments = $
"/u {Path.Combine(ServiceFolder, ServiceExecutableName)}"
var p = Process.Start(startInfo);
p.WaitForExit();
(ops.Status(ServiceName) ==
MessageBox.Show(
"Service has been uninstalled"
/// Start our service.
/// First check to see if the service is running as attempting
/// to install while running leads to doom and gloom :-)
/// Install after the above check
InstallService()
Process.Start(startInfo);
"/i {Path.Combine(ServiceFolder, ServiceExecutableName)}"
How to Install/Uninstall .NET Windows Service [C#]
How to Grant Users Rights to Manage Services (Start, Stop, Etc.)
In this article, a utility has been presented to easily automate the installing/uninstalling a Windows Service along with the current status of a service and the ability to start and stop a Windows Service. By using this utility a developer can spend more time on the actual service then being concerned with the install and uninstall processes of the service,