在 C# 开发中,对 Windows 服务进行生命周期管理往往涉及大量重复的 API 调用。为了简化运维脚本或后台管理程序的编写,这里整理了一套工具类,涵盖了服务的安装卸载、启停控制、状态检测及版本获取等核心功能。
前置条件
确保项目已添加以下命名空间引用,并具备管理员权限(部分操作如安装服务需要):
using System;
using System.Configuration.Install;
using System.IO;
using System.Reflection;
using System.ServiceProcess;
using Microsoft.Win32;
枚举定义
为了统一返回的服务状态,我们定义一个本地枚举,避免直接暴露 ServiceControllerStatus 的复杂性:
public enum ServiceStatus
{
CannotGet,
Stopped,
StartPending,
Running,
StopPending,
PausePending,
Paused,
ContinuePending
}
核心工具类
以下是完整的静态方法实现,建议将其保存为 WindowsServiceHelper.cs 以便复用。
服务信息查询
获取服务安装路径时,需从注册表读取 ImagePath 值。注意处理空引号的情况,否则路径解析会出错。
/// <summary>
/// 获取服务安装路径
/// </summary>
public static string GetWindowsServiceInstallPath(string serviceName)
{
string key = @"SYSTEM\CurrentControlSet\Services\" + serviceName;
using (var subKey = Registry.LocalMachine.OpenSubKey(key))
{
if (subKey == null) return string.Empty;
var path = subKey.GetValue("ImagePath").ToString();
path = path.Replace(, .Empty);
fi = FileInfo(path);
fi.Directory.ToString() + ;
}
}
{
services = ServiceController.GetServices();
( s services)
{
(s.ServiceName.ToLower() == nameService.ToLower())
;
}
;
}
{
ServiceStatus status = ServiceStatus.CannotGet;
scs = ServiceController.GetServices();
( sc scs)
{
(serviceName.ToUpper() == sc.ServiceName.ToUpper())
{
(sc.Status)
{
ServiceControllerStatus.Stopped: status = ServiceStatus.Stopped; ;
ServiceControllerStatus.StartPending: status = ServiceStatus.StartPending; ;
ServiceControllerStatus.Running: status = ServiceStatus.Running; ;
ServiceControllerStatus.StopPending: status = ServiceStatus.StopPending; ;
ServiceControllerStatus.PausePending: status = ServiceStatus.PausePending; ;
ServiceControllerStatus.Paused: status = ServiceStatus.Paused; ;
ServiceControllerStatus.ContinuePending: status = ServiceStatus.ContinuePending; ;
}
;
}
}
status;
}
{
(.IsNullOrEmpty(serviceName)) .Empty;
{
path = GetWindowsServiceInstallPath(serviceName) + + serviceName + ;
assembly = Assembly.LoadFile(path);
version = assembly.GetName().Version;
version.ToString();
}
(Exception ex)
{
Console.WriteLine();
.Empty;
}
}

