간단하게 서비스를 설치하는 기능에 대하여 설명하여 보았습니다.
서비스를 설치할 때 CreateService에 들어가는 인자들을 살펴보면 더 많은 무언가가 있어보이지만..
그건 진행하면서 필요할 때 하나씩 추가하는 걸로 해보죠..

자, 이제 서비스를 설치해봤으니, 제거를 해봐야 겠죠?
설치는 간단하지만, 제거는 좀더 복잡한 과정을 거쳐야합니다.

일단, 주의 사항으로 서비스는 제거하기 전에 꼭 멈추고 제거시켜야 한다는 것을 명심하세요.
단계는 서비스 열고, 중지 시키고, 제거한다.


DWORD ServiceUninstall()
{
    // 에러 처리를 위한 간단한 매크로
    #define ERROR_RETURN { RET = GetLastError(); goto ERROR_LABEL; }
    
    SC_HANDLE hSrv;
    DWORD RET = ERROR_SUCCESS;
    DWORD dwType;
    int loop = 0;
    SERVICE_STATUS ss;

    // SCM 을 열어서 서비스에 작업을 진행할 수 있도록 핸들을 하나 달라고 하자.
    SC_HANDLE hScm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
    
    // 열지 못하면 에러다. 머 어쩔 수 없다. 왜 그런지 에러 코드나 리턴한다.
    if (hScm == NULL)
        return GetLastError();
   
   
    // 서비스 관리자를 열었으니, 이제 서비스를 직접 열어보자.
    hSrv = OpenService(hScm, S_NAME, SERVICE_ALL_ACCESS);
    if (hSrv == NULL)
        ERROR_RETURN;
   
   
    // 관리자를 열어으면, 이젠 서비스의 상태를 읽어오자.
    // 서비스를 제거하려면 먼저, 서비스를 멈추어야 한다.

    loop = 0;
    do
    {
        ControlService(hSrv, SERVICE_CONTROL_INTERROGATE, &ss);
        Sleep(1);
    } while (++loop <10);
    dwType = ss.dwCurrentState;
   
   
    // 만약 서비스의 상태가 멈춤이 아니면, 서비스를 중지 시키자.
    if(dwType != SERVICE_STOPPED)
    {
        if(!ControlService(hSrv, SERVICE_CONTROL_STOP, &ss))
            ERROR_RETURN;
    }
   
   
    // 아주 무식한 방법으로, 서비스가 멈출 때 까지 기다린다.
    // 하지만 서비스를 멈춰야 하는데, 멈추지 않는다면?
    // 서비스를 제작한 사람을 쪼아야지.. 불쌍한 서비스 제거
    // 프로그램이 먹통되었다고 화내면 건강에 해롭다.
   
    // 만약 서비스를 멈추지 않고, 동작중인데 DeleteService를
    // 이용하여 제거하면, 컴터를 리부팅 하기 전까지는 다시
    // 설치가 불가능하다. (서비스 내부 디비엔트리에 먼가 찌꺼기가 남아서 안된다는데..흠...)

    do
    {
        Sleep(100);
       
        loop = 0;
        do
        {
            ControlService(hSrv, SERVICE_CONTROL_INTERROGATE, &ss);
            Sleep(1);
        } while (++loop <10);
        dwType = ss.dwCurrentState;
    } while(dwType != SERVICE_STOPPED);
   
   
    // 멈추어졌으면 제거한다.

    if(!DeleteService(hSrv))
        ERROR_RETURN;
   
ERROR_LABEL:
    if(hSrv)
        CloseServiceHandle(hSrv);
    if(hScm)
        CloseServiceHandle(hScm);
   
    return RET;
}

와우!!! 잘 살펴보면 알겠지만, 서비스를 제거할 때 필요한 것은 서비스를 제거할 수 있는 권한과, 서비스 이름만 알면된다.

+ Recent posts