LPHANDLER_FUNCTION_EX 콜백 함수(winsvc.h)
RegisterServiceCtrlHandlerEx 함수와 함께 사용되는 애플리케이션 정의 콜백 함수입니다. 서비스 프로그램은 이를 특정 서비스의 제어 처리기 함수로 사용할 수 있습니다.
LPHANDLER_FUNCTION_EX 형식은 이 함수에 대한 포인터를 정의합니다. HandlerEx 는 애플리케이션 정의 이름의 자리 표시자입니다.
이 함수는 RegisterServiceCtrlHandler 함수와 함께 사용되는 처리기 제어 처리기 함수를 대체합니다. 서비스는 두 컨트롤 처리기를 사용할 수 있지만 새 컨트롤 처리기는 사용자 정의 컨텍스트 데이터 및 추가 확장된 제어 코드를 지원합니다.
구문
LPHANDLER_FUNCTION_EX LphandlerFunctionEx;
DWORD LphandlerFunctionEx(
[in] DWORD dwControl,
[in] DWORD dwEventType,
[in] LPVOID lpEventData,
[in] LPVOID lpContext
)
{...}
매개 변수
[in] dwControl
컨트롤 코드입니다. 이 매개 변수는 다음 값 중 하나일 수 있습니다.
제어 코드 | 의미 |
---|---|
|
일시 중지된 서비스에 다시 시작해야 한다는 것을 알 수 있습니다. |
|
서비스에 현재 상태 정보를 서비스 제어 관리자에 보고하도록 알 수 있습니다.
처리기는 단순히 NO_ERROR 반환해야 합니다. SCM은 서비스의 현재 상태를 인식합니다. |
|
네트워크 서비스에 바인딩을 위한 새 구성 요소가 있음을 알 수 있습니다. 서비스는 새 구성 요소에 바인딩해야 합니다.
애플리케이션은 대신 플러그 앤 플레이 기능을 사용해야 합니다. |
|
네트워크 서비스에 바인딩 중 하나가 비활성화되었음을 알 수 있습니다. 서비스는 바인딩 정보를 다시 읽고 바인딩을 제거해야 합니다.
애플리케이션은 대신 플러그 앤 플레이 기능을 사용해야 합니다. |
|
비활성화된 바인딩이 사용하도록 설정되었음을 네트워크 서비스에 알 수 있습니다. 서비스는 바인딩 정보를 다시 읽고 새 바인딩을 추가해야 합니다.
애플리케이션은 대신 플러그 앤 플레이 기능을 사용해야 합니다. |
|
바인딩에 대한 구성 요소가 제거되었음을 네트워크 서비스에 알 수 있습니다. 서비스는 바인딩 정보를 다시 읽고 제거된 구성 요소에서 바인딩을 해제해야 합니다.
애플리케이션은 대신 플러그 앤 플레이 기능을 사용해야 합니다. |
|
서비스에 서비스별 시작 매개 변수가 변경되었다는 것을 알 수 있습니다. 서비스는 시작 매개 변수를 다시 읽어야 합니다. |
|
일시 중지해야 한다는 것을 서비스에 알 수 있습니다. |
|
시스템에 시스템이 종료될 것임을 알 수 있습니다. 시스템 종료 시 엄격한 시간 제한을 초과하여 정리 작업을 수행하는 데 추가 시간이 필요한 서비스는 이 알림을 사용할 수 있습니다. 서비스 제어 관리자는 해당 알림을 등록한 애플리케이션에 SERVICE_CONTROL_SHUTDOWN 알림을 보내기 전에 등록한 애플리케이션에 이 알림을 보냅니다.
이 알림을 처리하는 서비스는 서비스가 중지되거나 SERVICE_PRESHUTDOWN_INFO 통해 지정된 preshutdown 제한 시간 간격이 만료될 때까지 시스템 종료를 차단합니다. 이는 사용자 환경에 영향을 주므로 서비스는 다음 시스템 시작 시 데이터 손실 또는 상당한 복구 시간을 방지해야 하는 경우에만 이 기능을 사용해야 합니다. Windows Server 2003 및 Windows XP: 이 값은 지원되지 않습니다. |
|
서비스가 정리 작업을 수행할 수 있도록 시스템이 종료되고 있음을 서비스에 알려줍니다. SERVICE_CONTROL_PRESHUTDOWN 알림에 등록하는 서비스는 이미 중지되었으므로 이 알림을 받을 수 없습니다.
서비스에서 이 제어 코드를 수락하는 경우 정리 작업을 수행한 후 중지하고 NO_ERROR 반환해야 합니다. SCM이 이 제어 코드를 보낸 후에는 다른 제어 코드를 서비스에 보내지 않습니다. 자세한 내용은 이 항목의 ‘주의’ 섹션을 참조하세요. |
|
서비스에 중지해야 한다고 알 수 있습니다.
서비스에서 이 제어 코드를 수락하는 경우 수신 시 중지하고 NO_ERROR 반환해야 합니다. SCM이 이 제어 코드를 보낸 후에는 다른 제어 코드를 서비스에 보내지 않습니다. Windows XP: 서비스가 NO_ERROR 반환하고 계속 실행되면 제어 코드를 계속 받습니다. 이 동작은 Windows Server 2003 및 Windows XP SP2부터 변경되었습니다. |
이 매개 변수는 다음 확장된 제어 코드 중 하나일 수도 있습니다. 이러한 컨트롤 코드는 Handler 함수에서 지원되지 않습니다.
제어 코드 | 의미 |
---|---|
|
디바이스 이벤트의 서비스를 알 수 있습니다. ( RegisterDeviceNotification 함수를 사용하여 이러한 알림을 받으려면 서비스가 등록되어 있어야 합니다.) dwEventType 및 lpEventData 매개 변수에는 추가 정보가 포함되어 있습니다. |
|
컴퓨터의 하드웨어 프로필이 변경되었음을 서비스에 알 수 있습니다. dwEventType 매개 변수에는 추가 정보가 포함되어 있습니다. |
|
시스템 전원 이벤트의 서비스를 알 수 있습니다. dwEventType 매개 변수에는 추가 정보가 포함되어 있습니다. dwEventType이 PBT_POWERSETTINGCHANGE 경우 lpEventData 매개 변수에도 추가 정보가 포함됩니다. |
|
세션 변경 이벤트의 서비스를 알 수 있습니다. 로그온을 시도하기 전에 완전히 로드된 경우에만 서비스에 사용자 로그온 알림이 표시됩니다. dwEventType 및 lpEventData 매개 변수에는 추가 정보가 포함되어 있습니다. |
|
시스템에 시스템 시간이 변경되었음을 알 수 있습니다. lpEventData 매개 변수에는 추가 정보가 포함되어 있습니다. dwEventType 매개 변수는 사용되지 않습니다.
Windows Server 2008, Windows Vista, Windows Server 2003 및 Windows XP: 이 제어 코드는 지원되지 않습니다. |
|
서비스 트리거 이벤트에 대해 등록된 서비스에 이벤트가 발생했음을 알 수 있습니다.
Windows Server 2008, Windows Vista, Windows Server 2003 및 Windows XP: 이 제어 코드는 지원되지 않습니다. |
|
사용자가 다시 부팅을 시작했다는 것을 서비스에 알립니다.
Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 및 Windows XP: 이 제어 코드는 지원되지 않습니다. |
이 매개 변수는 다음 표에 설명된 대로 사용자 정의 제어 코드일 수도 있습니다.
제어 코드 | 의미 |
---|---|
|
서비스는 제어 코드와 연결된 작업을 정의합니다. |
[in] dwEventType
발생한 이벤트의 유형입니다. 이 매개 변수는 dwControl이 SERVICE_CONTROL_DEVICEEVENT, SERVICE_CONTROL_HARDWAREPROFILECHANGE, SERVICE_CONTROL_POWEREVENT 또는 SERVICE_CONTROL_SESSIONCHANGE 경우에 사용됩니다. 그렇지 않으면 0입니다.
dwControl이 SERVICE_CONTROL_DEVICEEVENT 경우 이 매개 변수는 다음 값 중 하나일 수 있습니다.
- DBT_DEVICEARRIVAL
- DBT_DEVICEREMOVECOMPLETE
- DBT_DEVICEQUERYREMOVE
- DBT_DEVICEQUERYREMOVEFAILED
- DBT_DEVICEREMOVEPENDING
- DBT_CUSTOMEVENT
dwControl이 SERVICE_CONTROL_SESSIONCHANGE 경우 이 매개 변수는 WM_WTSSESSION_CHANGE 메시지의 wParam 매개 변수에 지정된 값 중 하나일 수 있습니다.
[in] lpEventData
필요한 경우 추가 디바이스 정보입니다. 이 데이터의 형식은 dwControl 및 dwEventType 매개 변수의 값에 따라 달라집니다.
dwControl이 SERVICE_CONTROL_DEVICEEVENT 경우 이 데이터는 애플리케이션이 WM_DEVICECHANGE 메시지의 일부로 수신하는 lParam 매개 변수에 해당합니다.
dwControl이 SERVICE_CONTROL_POWEREVENTdwEventType이 PBT_POWERSETTINGCHANGE 경우 이 데이터는 POWERBROADCAST_SETTING 구조체에 대한 포인터입니다.
dwControl이 SERVICE_CONTROL_SESSIONCHANGE 경우 이 매개 변수는 WTSSESSION_NOTIFICATION 구조체에 대한 포인터입니다.
dwControl이 SERVICE_CONTROL_TIMECHANGE 경우 이 데이터는 SERVICE_TIMECHANGE_INFO 구조체에 대한 포인터입니다.
[in] lpContext
RegisterServiceCtrlHandlerEx에서 전달된 사용자 정의 데이터입니다. 여러 서비스가 프로세스를 공유하는 경우 lpContext 매개 변수는 서비스를 식별하는 데 도움이 될 수 있습니다.
반환 값
이 함수의 반환 값은 받은 컨트롤 코드에 따라 달라집니다.
다음 목록에서는 이 반환 값에 대한 규칙을 식별합니다.
- 일반적으로 서비스에서 컨트롤을 처리하지 않으면 ERROR_CALL_NOT_IMPLEMENTED 반환합니다. 그러나 서비스에서 처리하지 않더라도 SERVICE_CONTROL_INTERROGATE 대한NO_ERROR 반환해야 합니다.
- 서비스에서 SERVICE_CONTROL_STOP 또는 SERVICE_CONTROL_SHUTDOWN 처리하는 경우 NO_ERROR 반환합니다.
- 서비스에서 SERVICE_CONTROL_DEVICEEVENT 처리하는 경우 NO_ERROR 반환하여 요청을 부여하고 요청을 거부하는 오류 코드를 반환합니다.
- 서비스에서 SERVICE_CONTROL_HARDWAREPROFILECHANGE 처리하는 경우 NO_ERROR 반환하여 요청을 부여하고 요청을 거부하는 오류 코드를 반환합니다.
- 서비스에서 SERVICE_CONTROL_POWEREVENT 처리하는 경우 NO_ERROR 반환하여 요청을 부여하고 요청을 거부하는 오류 코드를 반환합니다.
- 서비스에서 처리하는 다른 모든 제어 코드의 경우 NO_ERROR 반환합니다.
설명
서비스가 시작되면 해당 ServiceMain 함수는 RegisterServiceCtrlHandlerEx 함수를 즉시 호출하여 제어 요청을 처리하는 HandlerEx 함수를 지정해야 합니다. 수락할 컨트롤 코드를 지정하려면 SetServiceStatus 및 RegisterDeviceNotification 함수를 사용합니다.
서비스의 기본 스레드에 있는 컨트롤 디스패처는 서비스 제어 관리자로부터 제어 요청을 받을 때마다 지정된 서비스에 대한 제어 처리기 함수를 호출합니다. 제어 요청을 처리한 후 서비스 상태가 변경되어 새 상태 서비스 제어 관리자에 보고하는 경우 제어 처리기는 SetServiceStatus를 호출해야 합니다.
제어 처리기 함수는 알림을 받고 즉시 반환하기 위한 것입니다. 콜백 함수는 해당 매개 변수를 저장하고 다른 스레드를 만들어 추가 작업을 수행해야 합니다. (애플리케이션은 서비스를 중지하기 전에 이러한 스레드가 종료되었는지 확인해야 합니다.) 특히 컨트롤 처리기는 교착 상태가 발생하거나 시스템이 응답을 중지할 수 있으므로 잠금을 수행하는 등 차단할 수 있는 작업을 피해야 합니다.
서비스 제어 관리자가 서비스에 제어 코드를 보내면 처리기 함수가 반환되기를 기다린 후 다른 서비스에 추가 제어 코드를 보냅니다. 컨트롤 처리기는 가능한 한 빨리 반환해야 합니다. 30초 이내에 반환되지 않으면 SCM은 오류를 반환합니다. 서비스에서 제어 처리기를 실행할 때 서비스가 긴 처리를 수행해야 하는 경우 긴 처리를 수행하는 보조 스레드를 만든 다음 컨트롤 처리기에서 반환해야 합니다. 이렇게 하면 서비스가 컨트롤 디스패처를 연결하고 다른 서비스가 제어 코드를 받지 못하도록 차단할 수 있습니다.
SERVICE_CONTROL_SHUTDOWN 제어 코드는 서비스 종료에 사용할 수 있는 제한된 시간(약 20초)이 있기 때문에 종료 중에 절대적으로 클린 서비스에 의해서만 처리되어야 합니다. 이 시간이 만료되면 서비스 종료가 완료되었는지 여부에 관계없이 시스템 종료가 진행됩니다. 시스템이 종료 상태로 남아 있는 경우(다시 시작되거나 전원이 끄지 않음) 서비스가 계속 실행됩니다. 서비스가 SERVICE_CONTROL_SHUTDOWN 수락하도록 등록하는 경우 제어 코드를 처리하고 NO_ERROR 반환해야 합니다. 이 제어 코드에 대한 오류를 반환하고 적시에 중지하지 않으면 시스템 종료가 진행되기 전에 시스템이 서비스 종료에 허용되는 전체 시간을 기다려야 하므로 시스템을 종료하는 데 필요한 시간이 늘어나게 될 수 있습니다.
서비스를 클린 데 더 많은 시간이 필요한 경우 서비스 컨트롤러가 서비스 종료가 완료되었다는 것을 시스템에 보고하기 전에 대기 시간을 알 수 있도록 대기 힌트와 함께 STOP_PENDING 상태 메시지를 보내야 합니다. 그러나 서비스가 종료를 중지하지 못하도록 하려면 서비스 컨트롤러가 대기하는 기간에 제한이 있습니다. 서비스가 서비스 스냅인을 통해 종료되는 경우 제한은 125초입니다. 운영 체제가 다시 부팅되는 경우 시간 제한은 다음 레지스트리 키의 WaitToKillServiceTimeout 값에 지정됩니다.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
플러그 앤 플레이 디바이스 이벤트를 최대한 빨리 처리해야 합니다. 그렇지 않으면 시스템이 응답하지 않을 수 있습니다. 이벤트 처리기가 실행을 차단할 수 있는 작업(예: I/O)을 수행하는 경우 다른 스레드를 시작하여 작업을 비동기적으로 수행하는 것이 가장 좋습니다.
서비스는 SetConsoleCtrlHandler 함수를 사용하여 종료 알림을 받을 수도 있습니다. 이 알림은 실행 중인 애플리케이션이 종료될 때 수신되며, 이는 서비스가 종료되기 전에 발생합니다.
요구 사항
요구 사항 | 값 |
---|---|
지원되는 최소 클라이언트 | Windows XP [데스크톱 앱만 해당] |
지원되는 최소 서버 | Windows Server 2003 [데스크톱 앱만 해당] |
대상 플랫폼 | Windows |
헤더 | winsvc.h(Windows.h 포함) |