지난 내용
[강좌로 보는 서비스 프로그래밍] 서비스란 무엇인가? [1/?]

[강좌로 보는 서비스 프로그래밍] 외적으로 보여지는 서비스 [2/?]
[강좌로 보는 서비스 프로그래밍] 설치와 제거 [3/?]
[강좌로 보는 서비스 프로그래밍] 가끔 쓸모있는 관련 함수들 [4/?]

이번에는 간단하게 설치된 서비스의 시작, 중지, 일시정지, 일시정지 풀기에 관한 내용을을 짤막하게 다루어 본다.

먼저 서비스 매니저의 핸들을 얻는다. 서비스 매니저의 핸들을 이용하여, 특정 서비스를 제어하는 것이 가능하다.
SC_HANDLE hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

서비스 매니저 핸들을 이용하여, 원하는 서비스를 오픈한다.
SC_HANDLE hSrv = OpenService(hScm, "열고자 하는 서비스의 이름", SERVICE_ALL_ACCESS);

해당 서비스의 핸들을 이용하여, 서비스를 시작한다.
StartService(hSrv, 0, NULL);

해당 서비스의 핸들을 이용하여, 서비스를 중지 시킨다.
SERVICE_STATUS ss;
ControlService(hSrv, SERVICE_CONTROL_STOP, &ss);

해당 서비스의 핸들을 이용하여, 서비스를 일시 중지 시킨다.
SERVICE_STATUS ss;
ControlService(hSrv, SERVICE_CONTROL_PAUSE, &ss);

해당 서비스의 핸들을 이용하여, 일시 중지된 서비스를 재개시킨다.
SERVICE_STATUS ss;
ControlService(hSrv, SERVICE_CONTROL_CONTINUE, &ss);

위와 같은 형태로 서비스의 동작 상태를 변경 하였을 때, 현재의 서비스 동작 상태를 읽어온다.
SERVICE_STATUS ss;
ControlService(hSrv,SERVICE_CONTROL_INTERROGATE,&ss);

// 지금까지 나온 SERVICE_STATUS 의 구조에 대하여 잠깐 살펴보자.
typedef struct _SERVICE_STATUS {
   DWORD   dwServiceType;                     // 서비스의 타입(파일드라이버/커널드라이버/일반서비스 ...)
   DWORD   dwCurrentState;                     // 서비스의 동작 상태
   DWORD   dwControlsAccepted;             // 서비스가 받을 수 있는 이벤트 설정 상태
   DWORD   dwWin32ExitCode;                  // 상태 변경주 에러가 발생했을 시 에러코드
   DWORD   dwServiceSpecificExitCode;    // 위와 같으나 좀 다르다.
   DWORD   dwCheckPoint;                       // 적당히 무시
   DWORD   dwWaitHint;                           // 적당히 무시
} SERVICE_STATUS, *LPSERVICE_STATUS;

그외에 설치할 때 당시의 여러 설정이나 상태를 변경하려면
ChangeServiceConfig 혹은 ChangeServiceConfig2  를 이용하여, 다양한 변경을 가해줄 수 있다.

서비스의 동작을 외부에서 제어했을 경우, 내부에서는 해당 상태에 맞도록 상태 설정을 처리해 주어야 한다.
(만약 내부에서 알맞게 상태를 변경하여 주지 않으면, 외부에서는 응답없음과 같은 기괴한 동작을 할것이다.)
SERVICE_STATUS ss;
ss.dwCurrentState = 원하는 상태;
SetServiceStatus(hSrv, &ss);

/* 설정 가능한 상태
#define SERVICE_STOPPED                        0x00000001
#define SERVICE_START_PENDING                  0x00000002
#define SERVICE_STOP_PENDING                   0x00000003
#define SERVICE_RUNNING                        0x00000004
#define SERVICE_CONTINUE_PENDING               0x00000005
#define SERVICE_PAUSE_PENDING                  0x00000006
#define SERVICE_PAUSED                         0x00000007
*/

저렇게 열어준 핸들은 사용후에 받드시 닫아주어야 한다.
CloseServiceHandle(hSrv);
CloseServiceHandle(hScm);

이전 장에서 서비스를 설치/제거, 여기서는 시작/중지를 확인하였으니, 다음 장에서는 서비스 본체에 대한 정리를 하고자 한다.
( 흐름을 보기 위한 부분으로 에러처리 없이 가장 간단한 형태로 설정이 되어 있으므로, 다음에는 추가적인 처리가 있을것이다.)

+ Recent posts