다음을 통해 공유


Service ServiceMain 함수

서비스 제어 프로그램이 새 서비스를 실행하도록 요청하면 SCM(서비스 제어 관리자)이 서비스를 시작하고 시작 요청을 컨트롤 디스패처에 보냅니다. 컨트롤 디스패처는 서비스에 대한 ServiceMain 함수를 실행하는 새 스레드를 만듭니다. 예제는 ServiceMain 함수 작성을 참조하세요.

ServiceMain 함수는 다음 작업을 수행해야 합니다.

  1. 모든 전역 변수를 초기화합니다.

  2. RegisterServiceCtrlHandler 함수를 즉시 호출하여 처리기 함수를 등록하여 서비스에 대한 제어 요청을 처리합니다. RegisterServiceCtrlHandler의 반환 값은 서비스 상태 SCM에 알리기 위해 호출에 사용되는 서비스 상태 핸들입니다.

  3. 초기화를 수행합니다. 초기화 코드의 실행 시간이 매우 짧을 것으로 예상되는 경우(1초 미만) ServiceMain에서 직접 초기화를 수행할 수 있습니다.

    초기화 시간이 1초보다 길어야 하는 경우 서비스는 다음 초기화 기술 중 하나를 사용해야 합니다.

    • SetServiceStatus 함수를 호출하여 SERVICE_RUNNING 보고하지만 초기화가 완료될 때까지는 컨트롤을 허용하지 않습니다. 이 서비스는 dwCurrentState가 SERVICE_RUNNING 설정되고 dwControlsAcceptedSERVICE_STATUS 구조에서 0으로 설정된 SetServiceStatus를 호출하여 이 작업을 수행합니다. 이렇게 하면 SCM이 준비되기 전에 서비스에 제어 요청을 보내지 않고 SCM에서 다른 서비스를 관리할 수 있습니다. 이 초기화 방법은 특히 자동 시작 서비스의 경우 성능에 권장됩니다.

    • SERVICE_START_PENDING 보고하고, 컨트롤을 허용하지 않고, 대기 힌트를 지정합니다. 서비스의 초기화 코드가 초기 대기 힌트 값보다 오래 걸릴 것으로 예상되는 작업을 수행하는 경우 코드는 SetServiceStatus 함수를 주기적으로 호출해야 합니다(수정된 대기 힌트 포함). 초기화가 진행되는 경우에만 SetServiceStatus 를 호출해야 합니다. 그렇지 않으면 SCM은 서비스가 진행 중이라고 가정하고 다른 서비스가 시작되지 않도록 차단하는 SERVICE_RUNNING 상태가 될 때까지 기다릴 수 있습니다. 초기화를 수행하는 스레드가 실제로 진행 중이라고 확신하지 않는 한 별도의 스레드에서 SetServiceStatus 를 호출하지 마세요.

      이 방법을 사용하는 서비스는 검사 지점 값을 지정하고 긴 초기화 중에 주기적으로 값을 증분할 수도 있습니다. 서비스를 시작한 프로그램은 QueryServiceStatus 또는 QueryServiceStatusEx를 호출하여 SCM에서 최신 검사 지점 값을 가져오고 값을 사용하여 사용자에게 증분 진행률을 보고할 수 있습니다.

  4. 초기화가 완료되면 SetServiceStatus 를 호출하여 서비스 상태를 SERVICE_RUNNING 설정하고 서비스가 수락할 준비가 된 컨트롤을 지정합니다. 컨트롤 목록은 SERVICE_STATUS 구조를 참조하세요.

  5. 서비스 작업을 수행하거나 보류 중인 작업이 없는 경우 호출자에게 제어를 반환합니다. 서비스 상태가 변경되면 SetServiceStatus를 호출하여 새 상태 정보를 보고해야 합니다.

  6. 서비스가 초기화되거나 실행되는 동안 오류가 발생하면 서비스는 SetServiceStatus 를 호출하여 정리가 길어질 경우 서비스 상태를 SERVICE_STOP_PENDING 설정해야 합니다. 정리가 완료되면 SetServiceStatus 를 호출하여 서비스 상태를 종료할 마지막 스레드에서 SERVICE_STOPPED 설정합니다. 오류를 식별하려면 SERVICE_STATUS 구조체의 dwServiceSpecificExitCodedwWin32ExitCode 멤버를 설정해야 합니다.

ServiceMain 함수 작성