Windows 서비스가 C #에 설치되어 있는지 확인하는 방법


79

동일한 컴퓨터에 설치된 GUI에 WCF 서비스를 노출하는 Windows 서비스를 작성했습니다. GUI를 실행할 때 서비스에 연결할 수없는 경우 서비스 앱이 아직 설치되지 않았기 때문인지 아니면 서비스가 실행되고 있지 않기 때문인지 알아야합니다. 전자 인 경우 여기에 설명 된대로 설치하고 싶습니다 . 후자의 경우 시작하고 싶습니다.

질문은 서비스가 설치되어 있는지 여부를 어떻게 감지하고 설치되었는지 감지하면 어떻게 시작합니까?

답변:


147

사용하다:

// add a reference to System.ServiceProcess.dll
using System.ServiceProcess;

// ...
ServiceController ctl = ServiceController.GetServices()
    .FirstOrDefault(s => s.ServiceName == "myservice");
if(ctl==null)
    Console.WriteLine("Not installed");
else    
    Console.WriteLine(ctl.Status);

고마워요-내가 필요했던 것!
— Shaul Behr

1
using (var sc = ServiceController.GetServices (). FirstOrDefault (s => s.ServiceName == "myservice"))-이것이 더 나은 접근 방식이라고 생각합니다.
— Alexandru Dicu 2013

4
@alexandrudicu : 어떻게 더 나은 접근 방식입니까? 경우 .GetServices()반환 100 ServiceController나머지를 무시하고 객체, 당신은 더 나은 정말 상당히있는 백 중 배치 하나입니다거야? 나는 그렇게 말하지 않을 것입니다.
— Allon Guralnek 2013

37

다음도 사용할 수 있습니다 ..

using System.ServiceProcess; 
... 
var serviceExists = ServiceController.GetServices().Any(s => s.ServiceName == serviceName);

3
IMO, 이것은 귀하의 서비스가 존재하는지 확인하는 가장 우아한 방법입니다. Linq의 힘을 활용하는 단 한 줄의 코드. 그건 그렇고, .ANY ()는 당신이 :-) '예 요청 / 아니오 질문을하지 않으려는 정확히 부울 반환
— 알렉스 X.

3
원격 컴퓨터에서 서비스를 확인해야하는 경우GetServices(string)
— ShooShoSha

7

실제로 다음과 같이 반복됩니다.

foreach (ServiceController SC in ServiceController.GetServices())

애플리케이션이 실행중인 계정에 서비스 속성을 볼 수있는 권한이없는 경우 액세스 거부 예외가 발생할 수 있습니다. 반면에 이러한 이름의 서비스가없는 경우에도 안전하게 수행 할 수 있습니다.

ServiceController SC = new ServiceController("AnyServiceName");

그러나 서비스가없는 경우 속성에 액세스하면 InvalidOperationException이 발생합니다. 서비스가 설치되었는지 확인하는 안전한 방법은 다음과 같습니다.

ServiceController SC = new ServiceController("MyServiceName");
bool ServiceIsInstalled = false;
try
{
    // actually we need to try access ANY of service properties
    // at least once to trigger an exception
    // not neccessarily its name
    string ServiceName = SC.DisplayName;
    ServiceIsInstalled = true;
}
catch (InvalidOperationException) { }
finally
{
    SC.Close();
}

감사! 그리고 다음과 같이 끝내시겠습니까? finally {SC.Close (); }
— Cel 2014

6
전체를 사용하여 포장하지 않으시겠습니까? using 문이 자동으로 삭제되므로 finally {SC.Close ()}가 필요하지 않습니다. using (ServiceController SC = new ServiceController ( "MyServiceName"))
— 청구서

2

비 linq의 경우 다음과 같이 배열을 반복 할 수 있습니다.

using System.ServiceProcess;

bool serviceExists = false
foreach (ServiceController sc in ServiceController.GetServices())
{
    if (sc.ServiceName == "myServiceName")
    {
         //service is found
         serviceExists = true;
         break;
    }
}

1

이 질문에 대한 최선의 답변이라고 생각합니다. 서비스가 존재하는지 확인하기 위해 추가 처리를 추가 할 필요가 없습니다. 그렇지 않은 경우 예외가 발생하기 때문입니다. 당신은 그것을 잡을 필요가 있습니다. 전체 메서드를 using ()으로 래핑하면 연결을 close () 할 필요도 없습니다.

using (ServiceController sc = new ServiceController(ServiceName))
{
 try
 {
  if (sc.Status != ServiceControllerStatus.Running)
  {
    sc.Start();
    sc.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 10));
    //service is now Started        
  }      
  else
    //Service was already started
 }
 catch (System.ServiceProcess.TimeoutException)
 {
  //Service was stopped but could not restart (10 second timeout)
 }
 catch (InvalidOperationException)
 {
   //This Service does not exist       
 }     
}

2
전혀 좋은 대답이 아닙니다. (1) 예외로 코드를 관리하는 것은 매우 나쁜 습관입니다. 비효율적이고 느리고 (2) 허용되는 대답은 깔끔하고 간결하며 요구 사항에 완벽하게 응답합니다. 자신의 대답으로 다이빙하기 전에 그것을 보셨습니까?
— Shaul Behr

원래 답변에는 포함되지 않은 서비스 시작 방법도 명확하게 물었 기 때문에 수락 된 답변처럼 읽는 방법을 모르는 것 같습니다.
— 법안

분명히 코드를 올바르게 작성하는 방법을 모릅니다. @Shaul Behr이 이미 언급했듯이 귀하의 접근 방식은 비효율적이고 느리기 때문에 나쁜 습관입니다. 자신의 대답을 말하는 것이 아마도 최고 일 것이며, 더 나빠질 것입니다. 여기에서 자기 칭찬은 결코 좋은 행동으로 간주되지 않습니다 (아마도 전 세계적으로).
— Yoda

1
분명히 나는 ​​무엇이 더 나쁜지 모르겠습니다 ... 당신이 말하는 것을 알고있는 것처럼 보이려고 시도 할 때 적절한 문법을 ​​사용하지 못하거나, 2014 년부터 스레드에 방금 댓글을 남긴 것을 깨닫지 못하는 당신의 무능력 .... Lol.
— 청구

이 사람이 그 존재를 확인하고 상호 작용 사이에 서비스를 삭제하면 어떻게되는지를 차지하는 유일한 해답이다
— 마이크 카론을

1
 private bool ServiceExists(string serviceName)
    {
        ServiceController[] services = ServiceController.GetServices();
        var service = services.FirstOrDefault(s => string.Equals(s.ServiceName, serviceName, StringComparison.OrdinalIgnoreCase));
        return service != null;
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.