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.