ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Windows 서비스 프로그램 개발 - 2
    Windows 프로그래밍 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 함수를 통해 지워주면 끝이다.

    이렇게 서비스를 제어하는 모든 과정은 다 알았다. 다음 글에서는 서비스에서 다른 프로그램을 실행하는 방법을 알아보자.

    댓글

Designed by Tistory.