Home Full Site
윈도우즈 서비스 프로그램 작성

윈도우즈 서비스 프로그램은 보통 Windows OS가 구동되면서 시스템에 의해 백그라운에서 자동으로 실행되는 프로그램이다. Windows Service 프로그램은 일반 콘솔이나 UI 프로그램과 달리, Session 0라고 불리우는 백그운드에서 실행되어 사용자가 UI 출력을 볼 수 없다. 따라서, 일반적으로 Event Log에 로그를 남기거나 파일과 같은 외부 저장 장치에 결과를 남기곤 한다.

윈도우즈 서비스 프로그램은 Windows Service 프로젝트 템플릿을 사용하여 작성하는데, 아래는 일반적인 작성 스텝을 요약한 것이다.
  1. VS에서 File => New Project => Windows Service 프로젝트 템플릿를 선택한다. Service Project Template
  2. 프로젝트 템플릿으로부터 생성된 Service1.cs 에서 Service1 클래스가 ServiceBase 클래스로부터 상속됨을 볼 수 있다. Service1 클래스의 OnStart() 메서드는 서비스가 시작될 때 실행되며, OnStop() 메서드는 서비스가 멈출 때 실행된다.
  3. 여기서는 간단한 예제로, OnStart()에서 5분마다 동작하는 타이머를 구동시켜, 매 5분마다 하나의 웹페이지를 읽어와서 파일에 저장하도록 한다. 아래 예제는 이러한 타이머 동작 부분을 Service1 에서 구현한 것이다.

예제

using System.Configuration;
using System.IO;
using System.Net;
using System.ServiceProcess;
using System.Timers;

namespace MyService
{
    public partial class Service1 : ServiceBase
    {
        private Timer timer;
        private string dataFolder;
      
        public Service1()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            // App.config에 DataFolder를 AppSettings 밑에 지정
            dataFolder = ConfigurationManager.AppSettings["DataFolder"];

            timer = new Timer();
            timer.Interval = 5 * 60 * 1000; // 5분 마다 실행
            timer.Elapsed += Timer_Elapsed;
            timer.Start();
        }

        private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            string outputFile = Path.Combine(dataFolder, "csharp-news.html");

            WebClient cli = new WebClient();
            cli.DownloadFile("http://csharp.tips", outputFile);
        }

        protected override void OnStop()
        {
        }
    }
}



서비스 인스톨러 추가 및 설정

윈도우즈 서비스 프로그램은 콘솔이나 UI 프로그램과 달리 윈도우즈의 SCM (Service Control Manager)에 의해 특별하게 관리된다. 서비스는 SCM에 의해 관리되도록 특별하게 설치되고 등록되어야 하는데, 이를 위해 VS 서비스 프로젝트에 Installer 컴포넌트를 추가하고 설정해 주어야 한다.

서비스 인스톨러를 추가하기 위해서는 Service 클래스의 디자인 화면으로 가서 (즉, 위 예제에서 Solution Explorer 상의 Server1.cs를 더블클릭함) 컨텍스트 메뉴 중 [Add Installer]를 선택하면 된다. 이 메뉴가 선택되면, 자동으로 ProjectInstaller.cs 가 생성되고 그 안에 아래 그림과 같이 serviceInstaller와 serviceProcessInstaller가 추가된다.

Windows Service Add Installer

여기에서 serviceInstaller를 클릭하면 속성창에서 설치하고자 하는 서비스의 고유한 서비스명과 서비스를 자동으로 시작할 지 여부 등을 설정할 수 있다. 아래 그림에서는 서비스명을 [MyService]로, 서비스 관리 매니저 (services.msc)에서의 표시명은 [My Service], 그리고 서비스 시작유형은 Manual 로 설정하였다. 또한, serviceProcessInstaller에서는 특히 서비스계정을 지정할 수 있는데, 아래에서는 LocalSystem 서비스 계정으로 지정하였다.

Windows Service Add Installer

마지막으로 Service 클래스의 디자인 화면으로 가서 F4를 누르고 속성창에 있는 서비스명(Service Name) 속성을 위에서 설정한 서비스명과 동일하게 설정한다. 즉, 위의 예에서와 같이 Service Name을 [MyService]로 변경한다. 이것을 변경하지 않으면, Event Viewer의 Source 컬럼에 서비스명이 제대로 표시되지 않는다. Event Viewer에는 서비스가 시작되거나 중지될 때 혹은 서비스에서 어떤 로그를 남길 때, 그 사항들이 서비스명과 함께 이벤트로 기록된다. Service Name

서비스 설치 및 실행

위와 같이 윈도우즈 서비스를 모두 작성하였으면, 이를 빌드한 후, VS에서 제공하는 InstallUtil.exe 를 실행하여 서비스를 OS에 설치한다. InstallUtil을 사용해 설치하기 위해서는 먼저 VS의 "Developer Command Prompt for VS2015"를 관리자 모드(Run as Administrator)로 실행하고, 아래와 같이 작성한 .EXE를 지정하면 된다.

Windows Service Install

설치된 서비스를 확인하기 위해서는 Services.msc 를 실행하여 서비스가 등록되었는지 체크한다. 아래 그림에서 My Service의 서비스 시작모드가 Manual이고, 서비스 계정이 Local System임을 확인할 수 있다.

Service Manager

설치된 서비스를 삭제하기 위해서는 InstallUtil.exe /u MyService.exe 명령을 수행하면 된다.

© csharpstudy.com