정리

[Win32] Service - #4 서비스 제어

저장소/VC++
[출처] 윈도우즈 API 정복, 김상형 지음


UI 디자인은 아래와 같다.



#define SVCNAME                        _T("MemStat")
#define SERVICE_CONTROL_NEWFILE        128

BOOL CControlDlg::OnInitDialog()
{
    /*
         중략...
    */

    hScm = ::OpenSCManager(NULL, NULL, GENERIC_READ);

    if(NULL == hScm)
    {
        MessageBox(_T("SCM을 열 수 없습니다."), _T("알림"), MB_OK);
        EndDialog(0);
    }

    hSvc = ::OpenService(hScm, SVCNAME, SERVICE_ALL_ACCESS);

    if(NULL == hSvc)
    {
        MessageBox(_T("MemStatService 서비스가 설치되어 있지 않습니다."), _T("알림"), MB_OK);

        ::CloseServiceHandle(hScm);
        EndDialog(0);
    }
    else
    {
        ::CloseServiceHandle(hSvc);
    }

    QueryService();
}

void CControlDlg::QueryService()
{
    hSvc = ::OpenService(hScm, SVCNAME, SERVICE_INTERROGATE);

    if(NULL == hSvc)
    {
        return;
    }

    do
    {
        ::ControlService(hSvc, SERVICE_CONTROL_INTERROGATE, &ss);
    }
    while(    (SERVICE_STOPPED != ss.dwCurrentState) &&
            (SERVICE_RUNNING != ss.dwCurrentState) &&
            (SERVICE_PAUSED != ss.dwCurrentState));

    GetDlgItem(IDC_BTN_START)->EnableWindow(FALSE);
    GetDlgItem(IDC_BTN_STOP)->EnableWindow(FALSE);
    GetDlgItem(IDC_BTN_PAUSE)->EnableWindow(FALSE);
    GetDlgItem(IDC_BTN_CONTINUE)->EnableWindow(FALSE);
    GetDlgItem(IDC_BTN_NEW_LOG)->EnableWindow(FALSE);

    switch(ss.dwCurrentState)
    {
    case SERVICE_STOPPED:
        {
            GetDlgItem(IDC_BTN_START)->EnableWindow(TRUE);
            GetDlgItem(IDC_STATIC)->SetWindowText(_T("현재 상태 : 중지"));
        }
        break;
    case SERVICE_RUNNING:
        {
            GetDlgItem(IDC_BTN_STOP)->EnableWindow(TRUE);
            GetDlgItem(IDC_BTN_PAUSE)->EnableWindow(TRUE);
            GetDlgItem(IDC_BTN_NEW_LOG)->EnableWindow(TRUE);
            GetDlgItem(IDC_STATIC)->SetWindowText(_T("현재 상태 : 실행중"));
        }
        break;
    case SERVICE_PAUSED:
        {
            GetDlgItem(IDC_BTN_STOP)->EnableWindow(TRUE);
            GetDlgItem(IDC_BTN_CONTINUE)->EnableWindow(TRUE);
            GetDlgItem(IDC_STATIC)->SetWindowText(_T("현재 상태 : 일시중지"));
        }
        break;
    }

    ::CloseServiceHandle(hSvc);
}

void CControlDlg::MemControl(DWORD dwControl)
{
    hSvc = ::OpenService(hScm, SVCNAME, GENERIC_EXECUTE);

    ::ControlService(hSvc, dwControl, &ss);

    ::CloseServiceHandle(hSvc);
    QueryService();
}

void CControlDlg::OnBnClickedBtnStart()
{
    // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.

    hSvc = ::OpenService(hScm, SVCNAME, SERVICE_START | SERVICE_QUERY_STATUS);

    // 서비스를 시작시키고 완전히 시작할 때까지 대기한다.
    SetCursor(LoadCursor(NULL, IDC_WAIT));
    {
        if(TRUE == ::StartService(hSvc, 0, NULL))
        {
            ::QueryServiceStatus(hSvc, &ss);

            while(SERVICE_RUNNING != ss.dwCurrentState)
            {
                Sleep(ss.dwWaitHint);
                ::QueryServiceStatus(hSvc, &ss);
            }
        }
    }
    SetCursor(LoadCursor(NULL, IDC_ARROW));

    ::CloseServiceHandle(hSvc);
    QueryService();
}

void CControlDlg::OnBnClickedBtnStop()
{
    // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.

    MemControl(SERVICE_CONTROL_STOP);
}

void CControlDlg::OnBnClickedBtnPause()
{
    // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.

    MemControl(SERVICE_CONTROL_PAUSE);
}

void CControlDlg::OnBnClickedBtnContinue()
{
    // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.

    MemControl(SERVICE_CONTROL_CONTINUE);
}

void CControlDlg::OnBnClickedBtnNewLog()
{
    // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.

    MemControl(SERVICE_CONTROL_NEWFILE);
}




'저장소 > VC++' 카테고리의 다른 글

[Win32] 시스템의 Locale 관련 함수들  (0) 2009.07.07
[Win32] IPC - #3 Pipe(파이프)  (0) 2009.05.14
[Win32] Service - #3 서비스 설치  (0) 2009.05.13
[Win32] Service - #2 서비스 생성  (0) 2009.05.13
[Win32] Service - #1 정의  (0) 2009.05.13