지난 내용
[강좌로 보는 서비스 프로그래밍] 서비스란 무엇인가? [1/?]
[강좌로 보는 서비스 프로그래밍] 외적으로 보여지는 서비스 [2/?]
[강좌로 보는 서비스 프로그래밍] 설치와 제거 [3/?]
[강좌로 보는 서비스 프로그래밍] 가끔 쓸모있는 관련 함수들 [4/?]
[강좌로 보는 서비스 프로그래밍] 시작/중지/일시정지 [5/?]
[강좌로 보는 서비스 프로그래밍] 서비스의 본체 코딩 [6/?]
[강좌로 보는 서비스 프로그래밍] 서비스의 본체 코딩 Cont. [6/?]
[강좌로 보는 서비스 프로그래밍] 뼈다귀 서비스 코드 [7/?]
[강좌로 보는 서비스 프로그래밍] 서비스의 디버깅 [8/?]
[강좌로 보는 서비스 프로그래밍] 내컴에 누가 왔는지 다알아 [9/?]
[강좌로 보는 서비스 프로그래밍] 환영 인사 [10/?]
[강좌로 보는 서비스 프로그래밍] 서비스의 동작 순서 [11/?]
[강좌로 보는 서비스 프로그래밍] 서비스의 종료 [12/?]

 
지금 까지의 진행한 내용을 정리하면서...

요번에 진행할 때는 좀 쓸만한 샘플을 제작해서 올려보려고 하였습니다. 하지만, 지금까지 사용한 샘플코드가 실무에 바로 적용할 수 있을 만큼
제대로 정리가 되지 못했더군요. 플젝만 복사해서 필요할 때 바로 사용할 수 있을 정도의 기본적인 정리를 하고 다음 순서를 진행하고자,
이번 장에서는 사용된 코드를 정리만 하고 넘기도록 하겠습니다. ^^;;;
(참고로 말씀드리면, VS 6.0과 VS2008 로 테스트 되었으며, 프로젝트도 해당 2가지 버전으로 빌드 가능하도록 구성되어 있습니다.)
(그리고, 여전히 땡땡 거리는 서비스입니다. -_-;;;)



프로젝트의 구성...


기본적인 서비스 골격을 가진 main.cpp
실제로 서비스 프로그래밍을 하면서 내부적으로 갖추어야할 기본적인 main() 함수부터 서비스 메인, 서비스 이벤트 핸들러 및 초기 구성에 필요한
모든 내용을 가지고 있는 소스입니다. 소스에는 아래의 6개 함수가 포함되어 있습니다.

main() 콘솔 응용 프로그램의 엔트리 함수 입니다. 전달받은 파라미터를 처리하는 기능을 담당하고, 필요한 경우 도움말을 보여줍니다.
service_main() 서비스에 등록되는 엔트리 함수 입니다. main에서 StartServiceCtrlDispatcher() 함수에 의하여 등록됩니다.
service_handler() 서비스의 이벤트를 받는 함수입니다. service_main 에서 RegisterServiceCtrlHandlerEx 함수에 의하여 등록됩니다.
EventServiceStop() 서비스가 중지되거나 종료될 때 호출되는 이벤트 함수입니다. service_handler 에서 호출됩니다.
EventServicePause() 서비스가 일시 중지될 때 호출되는 이벤트 함수입니다. service_handler 에서 호출됩니다.
EventServiceContinue() 일시중지된 상에서 서비스가 재개될 때 호출되는 이벤트 함수입니다. service_handler 에서 호출됩니다.

서비스 시스템을 관리하는데 필요한 기능을 가진 servicemgr.h 와 servicemgr.cpp
main.cpp 소스는 내부적으로 순수하게 서비스의 기능 구현에 필요한 루틴을 처리한다면, servicemgr 은 실제 서비스를 등록, 제거, 시작, 종료
등과 같은 서비스를 매니징하는데 필요한 모든 기능을 내부적으로 구현하고 있습니다. 해당 기능을 이용하면, services.msc 와 같은 매니저를
이용하지 않고서도 코딩으로 모든 서비스를 제어할 수 있습니다.

서비스에 필요는 하지만, 서비스 자체의 기능과는 먼 유틸리티 serviceutil.h 와 serviceutil.cpp
서비스는 응용 프로그램과는 다른 레이어에서 구동하고, LocalSystem 권한을 가진상태에서 동작하기 때문에, 의외로 제약 사항들이 있습니다.
이러한 부분을 처리하고, 터미널과 같은 상태에서의 동작 처리를 위한 몇몇가지 기능을 가지고 있습니다.

주어진 기능을 테스트하기 위한 코드 readme.txt
위에서 나열된 기능을 하나씩 테스트하기 위하여 제작했던 샘플 코드를 소스에 넣어두니, 상당히 지저분해서... ㅎ~ readme.txt 에 모아 두었습니다.

서비스 매니징을 위한 파리미터 처리 및 도움말 ( -help, -? )
소스를 보시면 아시겠지만, 위 프로젝트로 서비스를 제작하면 설치부터 제거까지 해당 실행파일 내부에 모두 탑재하게 됩니다. 이러한 기능은
작성한 서비스 뿐만 아니라, -srvname 이라는 옵션을 이용하여, 다른 서비스 이름을 옵션으로 전달해주면 시스템에 설치되어 있는 모든 서비스에
그대로 적용되도록 구성되어 있습니다.

만약 불필요한 서비스가 시스템에 존재한다면, 이를 제거할 때 아래과 같이 제거할 수 있습니다.
예) 서비스프로그램.exe -srvname=쓰레기서비스 -uninstall
D:\Personal\Kwon\서비스\SRVAPP\Debug>SRVAPP.exe -srvname=TEST -uninstall
Uninstall: [TEST] Success


중지되어 있는 다른 서비스를 프로그램적으로 시작해야 할경우, 서비스 내부 코드를 이용할 수도 있지만 다음과 같이 가능합니다.
(아래의 예를 system(), ShellExecute(), ShellExecuteEx(), CreateProcess() 등을 사용하여 구동시킬 수 있습니다.)
예) 서비스프로그램.exe -srvname=해당서비스 -start
D:\Personal\Kwon\서비스\SRVAPP\Debug>SRVAPP.exe -srvname=WebClient -start
Start: [WebClient] Success


만약 다른 서비스의 상태를 살펴볼 경우 아래와 같이 수행하여 살펴볼 수 있습니다.
예) 서비스프로그램.exe -srvname=다른서비스 -status
D:\Personal\Kwon\서비스\SRVAPP\Debug>SRVAPP.exe -srvname=Browser -status
Selected Service Status
   Service Name         > Browser
   Service Display Name > Computer Browser
   Service Descriptipn  >
Maintains an updated list of computers on the network and supplies this list to
computers designated as browsers. If this service is stopped, this list will not
 be updated or maintained. If this service is disabled, any services that explic
itly depend on it will fail to start.

   Service Start User   > LocalSystem
   Service Module Path  > C:\WINDOWS\system32\svchost.exe -k netsvcs
   Service Dependency   > LanmanWorkstation
   Service Start Type   > SERVICE_AUTO_START
   Service Run State    > SERVICE_RUNNING




서비스의 구동...

서비스를 처음으로 다루어 보는 분들을 위하여, 현재 만들어져 가고 있는 서비스와 이미 구동되고 있는 서비스들의 동작 방식을 다이어 그램으로
설명해 보려 합니다. 여기서 제시하는 방식은 콘솔에서 실행파일 상태로 바로 실행시켜 볼 수도 있도록 구성되어 있으므로, 기존 서비스와는 조금
다른 로직을 타기는 하지만 전체적인 흐름에 따른 차이는 크지 않습니다. 푸른색으로 명시된 함수명들은 main.cpp 에서 설명된 6개의 함수입니다.



나머지 자세한 사항들은 소스를 참조하시면 될꺼구요, 혹시나 서비스를 구현하는데 따른 문제점이나, 샘플로 제작하기 알맞은 내용등이
있으면 리플남겨 주세요.. ^^;;;
(요즘 서버군이 대부분 64비트머신이라, 테스트도 할겸 플젝내부에 64비트 빌드도 추가로 포함시켰습니다.)

SRVAPP.zip

+ Recent posts