본문 바로가기

~2009.12.31/software tale

[Win32] SERVICE Logic Flow

젝일, 윈도우즈 개발경험이 거의 없다시피하는 나로써,
어쩔수 없이 서버단에 올라가는 데몬(Service)을 만들기위해 이틀간 삽질하고
알아낸 사실이다.

예제 프로그램을 내가 이해하지 못했을까?
하여튼, StartServiceDispatcher 가 계속 fail 을 내는 동안 담배만 수개피 핀거같다.

저놈의 Dispatcher Error : [오류 1053] 이 왜나는지 알수 없었던 나는
오래전 2004년도에 hotfix 자료 가지고 고민도 해봤는데, XP SP2 를 쓰는 나로썬
당근 볼 필요도 없는 자료였다.

근데, 왜! 이런 로직 flow 를 아무도 알려주지 않는거지??!!  +.+
다들 알고 있는데 나만 몰랐던걸까? ㅠㅠ.


02/22/2007, 21:30:50
    lieps:ServiceMainProc() Start
    Service ONM_BRIDGE_MGR installed
02/22/2007, 21:30:50
    lieps:Install() End
    lieps: Installed
    lieps: ServiceMainProc() End
02/22/2007, 21:34:04
    lieps:ServiceMainProc() Start
    lieps: ExecuteSubProcess() start
    lieps:ServiceMain() Start

처음 programName -install 시 main()에서 시작해서 install()를 실행하여
SCM을 오픈하고 서비스에 등록
서비스 메뉴를 열어서(혹은 실행하여) 서비스를 시작하면, 프로그램이 다시
실행되는데, 이때 main()에 argv 가 없는 상태이므로 StartServiceCtrlDispatcher() 실행된다. 그러면서 ServiceMain()를 호출하는거지... +.+
SCM에 프로그램이 등록된 상태에서 Dispatcher 는  SERVICE_TABLE_ENTRY 에 ServiceMain을 구동시킨다.

즉;
    1. SCM을 오픈하고 서비스에 등록시킨다.
    2. SCM에 의해 서비스가 실행이 되면서 StartServiceCtrlDispatcher() 가 실행

주의! 서비스에 먼저 등록되고 난 후 StartServiceCtrlDispatcher()가 실행되어야 함!

[ sample example! ]
-------------------
int main(int argc, char **argv)
{
    // 서비스 테이블 정의
    SERVICE_TABLE_ENTRY ste[]={
        {"MemStat", (LPSERVICE_MAIN_FUNCTION)MyServiceMain},
        {NULL, NULL}
    };

/*
아무런 옵션이 없을 경우 마지막 else 문으로 빠지면서 StartServiceCtrlDispatcher() 가 실행된다.
그러나 서비스에 등록되지 않았기때문에 StartServiceCtrlDispatcher 연결 실패가 일어나면서 return 0;
-install 옵션이 붙을경우 install()에 의해 서비스가 등록되고 return 으로 끝난다.
install 에 의해 일단 서비스가 등록된다.
그리고 서비스에서 "시작" 버튼을 눌렸을때, main() 이 다시한번 실행하되 이번에는 argv가 붙지 않으므로
마지막 else 문이 시작되나 서비스가 등록된 상태이므로 StartServiceCtrlDispatcher() 함수가 정상적으로
Dispatcher Thread 를 시작하게 되며 ServiceMain()를 호출하게 된다.
Dispatcher Thread 는 ServiceMain()가 종료되지 전까지 대기한다.
*/

    if( argc >= 2 ) {
        if( strcmp(argv[1], "-install") == 0 )
            install();
        else if( strcmp(argv[1], "-remove") == 0 )
            uninstall();
    }
    else {
        printf("Usage : %s [-install][-remove]\n", argv[0]);

        if( StartServiceCtrlDispatcher(ste) != 0)
            printf("StartServiceCtrlDispatcher ok!\n");
        else
            printf("Dispatcher error!\n");
    }
    return 0;
}
-----

휴- 인제 잘 동작한다.
근데, 오랫동안 윈도즈 개발 해본적이 없어서 힘들었다. ...ㅜ.ㅜ 삐질..