检查特定机器上是否存在服务,而不使用exception处理

不知道是否有更好的方法来做到这一点,所以这是问题的原因。 我可以使用下面的代码检查特定机器上是否存在服务:

bool DoesServiceExist(string serviceName, string machineName) { ServiceController controller = null; try { controller = new ServiceController(serviceName, machineName); controller.Status; return true; } catch(InvalidOperationException) { return false; } finally { if (controller != null) { controller.Dispose(); } } } 

但对我来说这似乎是一个无效的解决scheme(由于exception处理)。 有没有更好的方法来检查服务是否存在。 注意 – 我最近转向.Net 4.0,所以如果有人知道在4.0中更好的解决scheme是可以接受的。

编辑:这是一个示例c#控制台应用程序来testing我的示例以及GetServices代码示例的性能。 在我的testing中,我发现GetServices在服务不存在的情况下性能要好得多,但在服务存在的时候速度要慢两倍:

  static void Main(string[] args) { string serviceName = string.Empty; string machineName = string.Empty; var sw = new Stopwatch(); sw.Reset(); sw.Start(); for (int i = 0; i < 1000; i++) { ServiceExistsException(serviceName, machineName); } sw.Stop(); Console.WriteLine("Elapsed time: " + sw.ElapsedMilliseconds.ToString()); sw.Reset(); sw.Start(); for (int i = 0; i < 1000; i++) { ServiceExistsGetList(serviceName, machineName); } sw.Stop(); Console.WriteLine("Elapsed time: " + sw.ElapsedMilliseconds.ToString()); Console.WriteLine("Done"); Console.ReadLine(); } static bool ServiceExistsException(string serviceName, string machineName) { ServiceController controller = null; try { controller = new ServiceController(serviceName, machineName); string name = controller.DisplayName; return true; } catch (InvalidOperationException) { return false; } finally { if (controller != null) { controller.Dispose(); } } } static bool ServiceExistsGetList(string serviceName, string machineName) { ServiceController[] services = null; try { services = ServiceController.GetServices(machineName); var service = services.FirstOrDefault(s => s.ServiceName == serviceName); return service != null; } finally { if (services != null) { foreach (ServiceController controller in services) { controller.Dispose(); } } } } } 

您可以使用ServiceController.GetServices()方法获取机器上的所有服务,然后查看它们以查看是否存在指定您正在查找的内容:

 bool DoesServiceExist(string serviceName, string machineName) { ServiceController[] services = ServiceController.GetServices(machineName); var service = services.FirstOrDefault(s => s.ServiceName == serviceName); return service != null; } 

FirstOrDefault()扩展方法(来自System.Linq )将返回具有给定名称的第一个服务,如果不匹配则返回null


为了解决您的速度问题:

不pipe服务是否被find,单个方法调用的两种方法之间的区别是微不足道的。 这只会是一个问题,如果你打电话这个方法数千次 – 在这种情况下得到的服务列表一次,并记住它。

与adrianbanks一样的方法,但稍微更紧凑的代码。 如果你使用LINQ,你可以使用任何语句来返回你想要的。 另外,如果您正在本地计算机上查看,则不需要提供计算机名称。

 bool DoesServiceExist(string serviceName) { return ServiceController.GetServices().Any(serviceController => serviceController.ServiceName.Equals(serviceName)); } 

build立在迈克的答案之上。 与Dictionary.TryGetValue相同的概念。

  /// <summary> /// Gets a <see cref="ServiceController"/> given the specified <see cref="pServiceName"/>. /// </summary> /// <param name="pServiceName">The name of the service.</param> /// <param name="pService">The <see cref="ServiceController"/> associated with the name.</param> /// <returns> /// <see cref="bool.True"/> if the <see cref="ServiceController"/> exists; otherwise <see cref="bool.False"/>. /// </returns> private static bool TryGetService(string pServiceName, out ServiceController pService) { pService = ServiceController.GetServices() .FirstOrDefault(serviceController => serviceController.ServiceName == pServiceName); return pService != null; }