服务控制器类扩展实现

在.NET框架中,ServiceController类提供了管理和操作Windows服务的功能。然而,它并不提供获取服务可执行文件路径的功能。为了实现这一功能,需要对ServiceController类进行扩展。本文将介绍如何通过继承的方式实现这一功能,并讨论相关的安全处理。

扩展ServiceController类

扩展ServiceController类的主要目的是添加获取服务可执行文件路径的功能。可以通过继承ServiceController类并添加新的属性和方法来实现这一目标。

首先,添加一个新的属性ImagePath,用于获取服务的可执行文件路径。这个属性的值在第一次调用时获取,而不是在实例化时获取。这样可以提高效率,但也意味着如果在从远程机器获取数据时连接被断开,可能会得到不可预测的结果。

public class ServiceController : System.ServiceProcess.ServiceController { private string m_ImagePath; public string ImagePath { get { if (m_ImagePath == null) { m_ImagePath = GetImagePath(); } return m_ImagePath; } } // 其他代码... }

接下来,重写DependentServices和ServicesDependedOn属性,使它们返回ServiceController类型的数组,而不是System.ServiceProcess.ServiceController类型的数组。

public new ServiceController[] DependentServices { get { if (m_DependentServices == null) { m_DependentServices = ServiceController.GetServices(base.DependentServices); } return m_DependentServices; } } public new ServiceController[] ServicesDependedOn { get { if (m_ServicesDependedOn == null) { m_ServicesDependedOn = ServiceController.GetServices(base.ServicesDependedOn); } return m_ServicesDependedOn; } }

最后,重写GetServices静态方法,使其返回ServiceController类型的数组。

public static new ServiceController[] GetServices() { return GetServices("."); } public static new ServiceController[] GetServices(string machineName) { return GetServices(System.ServiceProcess.ServiceController.GetServices(machineName)); } private static ServiceController[] GetServices(System.ServiceProcess.ServiceController[] systemServices) { List services = new List(systemServices.Length); foreach (System.ServiceProcess.ServiceController service in systemServices) { services.Add(new ServiceController(service.ServiceName, service.MachineName)); } return services.ToArray(); }

使用扩展的ServiceController类

使用扩展后的ServiceController类非常简单。只需要调用GetServices方法获取服务列表,然后遍历这个列表,就可以获取每个服务的名称、显示名称和可执行文件路径。

static void Main(string[] args) { ServiceController[] services = ServiceController.GetServices("bwdemo"); foreach (ServiceController service in services) { Console.WriteLine("ServiceName: {0}; DisplayName: {1}", service.ServiceName, service.DisplayName); Console.WriteLine("Image Path: {0}\n", service.ImagePath); } Console.ReadLine(); }

处理安全问题

在处理远程服务时,安全是一个重要的考虑因素。ServiceController类本身并不处理安全模拟,因此需要在调用代码中处理。虽然作者没有亲自测试,但如果aleksisa的代码可以工作,那么这部分代码也应该可以工作。

此外,如果只需要获取服务列表,那么在远程计算机上设置相同的用户名和密码就足够了。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485