지난 내용
[강좌로 보는 서비스 프로그래밍] 서비스란 무엇인가? [1/?]
[강좌로 보는 서비스 프로그래밍] 외적으로 보여지는 서비스 [2/?]
[강좌로 보는 서비스 프로그래밍] 설치와 제거 [3/?]
[강좌로 보는 서비스 프로그래밍] 가끔 쓸모있는 관련 함수들 [4/?]
[강좌로 보는 서비스 프로그래밍] 서비스란 무엇인가? [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);
ControlService(hSrv, SERVICE_CONTROL_STOP, &ss);
해당 서비스의 핸들을 이용하여, 서비스를 일시 중지 시킨다.
SERVICE_STATUS ss;
ControlService(hSrv, SERVICE_CONTROL_PAUSE, &ss);
ControlService(hSrv, SERVICE_CONTROL_PAUSE, &ss);
해당 서비스의 핸들을 이용하여, 일시 중지된 서비스를 재개시킨다.
SERVICE_STATUS ss;
ControlService(hSrv, SERVICE_CONTROL_CONTINUE, &ss);
ControlService(hSrv, SERVICE_CONTROL_CONTINUE, &ss);
위와 같은 형태로 서비스의 동작 상태를 변경 하였을 때, 현재의 서비스 동작 상태를 읽어온다.
SERVICE_STATUS ss;
ControlService(hSrv,SERVICE_CONTROL_INTERROGATE,&ss);
그외에 설치할 때 당시의 여러 설정이나 상태를 변경하려면
ChangeServiceConfig 혹은 ChangeServiceConfig2 를 이용하여, 다양한 변경을 가해줄 수 있다.
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;
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
*/
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);
CloseServiceHandle(hScm);
이전 장에서 서비스를 설치/제거, 여기서는 시작/중지를 확인하였으니, 다음 장에서는 서비스 본체에 대한 정리를 하고자 한다.
( 흐름을 보기 위한 부분으로 에러처리 없이 가장 간단한 형태로 설정이 되어 있으므로, 다음에는 추가적인 처리가 있을것이다.)