Windows 프로그래밍
Windows 서비스 프로그램 개발 - 2
쨉
2019. 1. 8. 13:29
예에~ 2탄이다!!
1탄에서 Create와 Start하는 함수를 살펴봤으니 2탄에서는 Stop과 Delete하는 함수에 대해 알아보자.
Stop 과정
BOOL CService::StopServiceProc(WCHAR *ServiceName) { CString ErrorString; SC_HANDLE SCMhandle = NULL; SC_HANDLE OpenSChandle = NULL; SCMhandle = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (SCMhandle == NULL) { int Err = GetLastError(); ErrorString.Format(L"Stop OpenSCManager : %d", Err); AfxMessageBox(ErrorString); return 0; } OpenSChandle = ::OpenService(SCMhandle, ServiceName, SERVICE_ALL_ACCESS); if (OpenSChandle == NULL) { CloseServiceHandle(SCMhandle); int Err = GetLastError(); ErrorString.Format(L"Stop OpenSCManager : %d", Err); AfxMessageBox(ErrorString); return 0; } SERVICE_STATUS ss; BOOL StatusResult = ::QueryServiceStatus(OpenSChandle, &ss); if (StatusResult == FALSE) { CloseServiceHandle(SCMhandle); CloseServiceHandle(OpenSChandle); int Err = GetLastError(); ErrorString.Format(L"Stop QueryServiceStatus : %d", Err); AfxMessageBox(ErrorString); return 0; } if (ss.dwCurrentState != SERVICE_STOPPED) { BOOL ControlResult = ::ControlService(OpenSChandle, SERVICE_CONTROL_STOP, &ss); if (!ControlResult) { CloseServiceHandle(SCMhandle); CloseServiceHandle(OpenSChandle); int Err = GetLastError(); ErrorString.Format(L"Stop ControlService : %d", Err); AfxMessageBox(ErrorString); return 0; } } CloseServiceHandle(SCMhandle); CloseServiceHandle(OpenSChandle); return TRUE; }
Create든 Start든 Stop이든 다 같아 보여서 사기치는줄 알 수도 있지만 실제로 다 비슷하다.
이번에도 역시 서비스를 제어하기 위해 SCManager를 열어준다. 물론 옵션도 SC_MANAGER_ALL_ACCESS로.
SCManager가 정상적으로 열렸다면 OpenService를 통해 서비스의 핸들을 받고 QueryServiceStatus 함수에서 해당 서비스의 상태를 알아낸다. (이렇게 함수를 표시하니까 더 찾기 쉬운 것 같다. 앞으론 이렇게 해야지)
서비스가 SERVICE_STOPPED 말 그대로 정지한 상태가 아니라면 ControlService 함수를 통해 정지시켜준다.
Delete 과정
BOOL CService::DeleteServiceProc(WCHAR *ServiceName) {
CString ErrorString;
SC_HANDLE SCMhandle = NULL;
SC_HANDLE OpenSChandle = NULL;
SCMhandle = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (SCMhandle == NULL) {
int Err = GetLastError();
ErrorString.Format(L"Stop OpenSCManager : %d", Err);
AfxMessageBox(ErrorString);
return 0;
}
OpenSChandle = ::OpenService(SCMhandle, ServiceName, SERVICE_ALL_ACCESS);
if (OpenSChandle == NULL) {
CloseServiceHandle(SCMhandle);
int Err = GetLastError();
ErrorString.Format(L"Stop OpenSCManager : %d", Err);
AfxMessageBox(ErrorString);
return 0;
}
BOOL DeleteResult = ::DeleteService(OpenSChandle);
if (DeleteResult == FALSE) {
CloseServiceHandle(SCMhandle);
CloseServiceHandle(OpenSChandle);
int Err = GetLastError();
ErrorString.Format(L"Stop OpenSCManager : %d", Err);
AfxMessageBox(ErrorString);
return 0;
}
CloseServiceHandle(SCMhandle);
CloseServiceHandle(OpenSChandle);
return TRUE;
}
이제 SCManager와 서비스를 여는 단계까지는 익숙할 것이다.
Delete 과정은 Stop 과정보다 더 쉽다. 그냥 DeleteService 함수를 통해 지워주면 끝이다.
이렇게 서비스를 제어하는 모든 과정은 다 알았다. 다음 글에서는 서비스에서 다른 프로그램을 실행하는 방법을 알아보자.