代码之家  ›  专栏  ›  技术社区  ›  pstrjds

在不使用异常处理的情况下检查特定计算机上是否存在服务

  •  46
  • pstrjds  · 技术社区  · 14 年前

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

    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();
             }
        }
    }
    

    但对于我来说,这似乎是一个效率低下的解决方案(由于异常处理)。有没有更好的方法来检查服务是否存在?注意-我最近已经切换到.NET 4.0,所以如果有人知道4.0中更好的解决方案,这是可以接受的。

    编辑: 下面是一个示例C控制台应用程序,用于测试我的示例以及GetServices代码示例的性能。在我的测试中,我发现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();
                    }
                }
            }
        }
    }
    
    3 回复  |  直到 7 年前
        1
  •  81
  •   Michael Myers KitsuneYMG    12 年前

    你可以使用 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 如果没有匹配。


    要解决速度问题:

    对于单个方法调用,无论是否找到服务,这两种方法之间的差异都可以忽略不计。只有当您数千次调用此方法时才会出现问题,在这种情况下,只需获取一次服务列表并记住它。

        2
  •  15
  •   Beetee Vladislav Zalesak    7 年前

    与Adrianbanks的方法相同,但代码稍微紧凑一些。 如果您使用的是LINQ,那么可以使用任何语句返回所需的内容。 此外,如果您正在检查本地计算机,则无需提供计算机名称。

    bool DoesServiceExist(string serviceName)
    {
       return ServiceController.GetServices().Any(serviceController => serviceController.ServiceName.Equals(serviceName));
    }
    
        3
  •  4
  •   Shawn    8 年前

    建立在迈克的回答之上。同一概念 字典.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;
        }