共用方式為


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

控制件程式代碼。 此參數可以是下列其中一個值。

控制程序代碼 意義
SERVICE_CONTROL_CONTINUE
0x00000003
通知暫停的服務應該繼續。
SERVICE_CONTROL_INTERROGATE
0x00000004
通知服務向服務控制管理員報告其目前狀態資訊。

處理程式應該只會傳回 NO_ERROR;SCM 知道服務的目前狀態。

SERVICE_CONTROL_NETBINDADD
0x00000007
通知網路服務有新的元件可供系結。 服務應該系結至新的元件。

應用程式應該改用 隨插即用 功能。

SERVICE_CONTROL_NETBINDDISABLE
0x0000000A
通知網路服務已停用其中一個系結。 服務應該重新讀取其系結資訊,並移除系結。

應用程式應該改用 隨插即用 功能。

SERVICE_CONTROL_NETBINDENABLE
0x00000009
通知網路服務已啟用停用的系結。 服務應該重新讀取其系結資訊,並新增新的系結。

應用程式應該改用 隨插即用 功能。

SERVICE_CONTROL_NETBINDREMOVE
0x00000008
通知網路服務已移除系結的元件。 服務應該重新讀取其系結資訊,並從移除的元件解除系結。

應用程式應該改用 隨插即用 功能。

SERVICE_CONTROL_PARAMCHANGE
0x00000006
通知服務服務特定啟動參數已變更。 服務應該重新讀取其啟動參數。
SERVICE_CONTROL_PAUSE
0x00000002
通知服務應該暫停。
SERVICE_CONTROL_PRESHUTDOWN
0x0000000F
通知服務系統即將關閉。 需要額外時間才能在系統關機時執行清除工作的服務可以使用此通知。 服務控制管理員會將此通知傳送給已註冊的應用程式,再將 SERVICE_CONTROL_SHUTDOWN 通知傳送給已註冊該通知的應用程式。

處理此通知的服務會封鎖系統關機,直到服務停止或透過 SERVICE_PRESHUTDOWN_INFO 到期所指定的預先逾時時間間隔為止。 由於這會影響用戶體驗,因此只有在絕對需要避免數據遺失或下次系統啟動時大幅復原時,服務才應該使用此功能。

Windows Server 2003 和 Windows XP: 不支援此值。

SERVICE_CONTROL_SHUTDOWN
0x00000005
通知服務系統正在關閉,讓服務可以執行清除工作。 請注意,註冊 SERVICE_CONTROL_PRESHUTDOWN 通知的服務無法接收此通知,因為它們已經停止。

如果服務接受此控制程式代碼,它必須在執行清除工作並傳回 NO_ERROR之後停止。 SCM 傳送此控制程式代碼之後,它不會將其他控制代碼傳送至服務。

如需詳細資訊,請參閱本主題的一節。

SERVICE_CONTROL_STOP
0x00000001
通知服務應該停止。

如果服務接受此控制程式代碼,則必須在收到時停止,並傳回 NO_ERROR。 SCM 傳送此控制程式代碼之後,它不會將其他控制代碼傳送至服務。 Windowsxp: 如果服務傳回 NO_ERROR 並繼續執行,它會繼續接收控制碼。 此行為從 Windows Server 2003 開始變更,以及 SP2 的 Windows XP。

 

此參數也可以是下列其中一個擴充控件程序代碼。 請注意, Handler 函式不支援這些控制程式代碼。

控制件程式代碼 意義
SERVICE_CONTROL_DEVICEEVENT
0x0000000B
通知裝置事件的服務。 (服務必須已註冊才能使用 RegisterDeviceNotification function.) dwEventTypelpEventData 參數包含其他資訊來接收這些通知。
SERVICE_CONTROL_HARDWAREPROFILECHANGE
0x0000000C
通知服務計算機的硬體配置檔已變更。 dwEventType 參數包含其他資訊。
SERVICE_CONTROL_POWEREVENT
0x0000000D
通知系統電源事件的服務。 dwEventType 參數包含其他資訊。 如果 dwEventTypePBT_POWERSETTINGCHANGE,lpEventData 參數也會包含其他資訊。
SERVICE_CONTROL_SESSIONCHANGE
0x0000000E
通知會話變更事件的服務。 請注意,只有在進行登入嘗試之前,服務才會收到使用者登入的通知。 dwEventTypelpEventData 參數包含其他資訊。
SERVICE_CONTROL_TIMECHANGE
0x00000010
通知服務系統時間已變更。 lpEventData 參數包含其他資訊。 不使用 dwEventType 參數。

Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP: 不支援此控制件程式代碼。

SERVICE_CONTROL_TRIGGEREVENT
0x00000020
通知服務註冊 的服務觸發程式事件 ,該事件已發生。

Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP: 不支援此控制件程式代碼。

SERVICE_CONTROL_USERMODEREBOOT
0x00000040
通知服務使用者已起始重新啟動。

Windows Server 2008 R2、Windows 7、Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP: 不支援此控制件程式代碼。

 

此參數也可以是使用者定義的控件程序代碼,如下表所述。

控制程序代碼 意義
範圍 128 到 255。
服務會定義與控件程式代碼相關聯的動作。

[in] dwEventType

已發生的事件類型。 如果 dwControl是SERVICE_CONTROL_DEVICEEVENTSERVICE_CONTROL_HARDWAREPROFILECHANGE、SERVICE_CONTROL_POWEREVENT或SERVICE_CONTROL_SESSIONCHANGE則會使用此參數。 否則為零。

如果 dwControl是SERVICE_CONTROL_DEVICEEVENT,此參數可以是下列其中一個值:

如果 dwControl是SERVICE_CONTROL_HARDWAREPROFILECHANGE,此參數可以是下列其中一個值: 如果 dwControl是SERVICE_CONTROL_POWEREVENT,這個參數可以是WM_POWERBROADCAST訊息之 wParam 參數中指定的其中一個值。

如果 dwControl是SERVICE_CONTROL_SESSIONCHANGE,這個參數可以是WM_WTSSESSION_CHANGE訊息 wParam 參數中指定的其中一個值。

[in] lpEventData

如有需要,其他裝置資訊。 此數據的格式取決於 dwControldwEventType 參數的值。

如果 dwControl是SERVICE_CONTROL_DEVICEEVENT,則此數據會對應至應用程式在WM_DEVICECHANGE訊息中接收的 lParam 參數。

如果 dwControlSERVICE_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_STOPSERVICE_CONTROL_SHUTDOWN,請 傳回NO_ERROR
  • 如果您的服務處理 SERVICE_CONTROL_DEVICEEVENT,請傳回 NO_ERROR 以授與要求,並傳回錯誤碼來拒絕要求。
  • 如果您的服務處理 SERVICE_CONTROL_HARDWAREPROFILECHANGE,請傳回 NO_ERROR 以授與要求,並傳回錯誤碼來拒絕要求。
  • 如果您的服務處理 SERVICE_CONTROL_POWEREVENT,請傳回 NO_ERROR 以授與要求,並傳回錯誤碼來拒絕要求。
  • 針對服務句柄的其他所有控制程式碼,傳回 NO_ERROR

備註

啟動服務時,其 ServiceMain 函式應該會立即呼叫 RegisterServiceCtrlHandlerEx 函式,以指定 HandlerEx 函式來處理控制要求。 若要指定要接受的控制程序代碼,請使用 SetServiceStatusRegisterDeviceNotification 函式。

每當從服務控制管理員收到控制件要求時,服務主線程中的控制發送器會叫用指定服務的控制程式函式。 處理控件要求之後,如果服務狀態變更以向服務控制管理員報告其新狀態,控件處理程式就必須呼叫 SetServiceStatus

控制處理程式函式的目的是要立即接收通知並傳回。 回呼函式應該儲存其參數,並建立其他線程來執行其他工作。 (您的應用程式必須確定這類線程在停止 service.) 之前已結束,特別是控制處理程式應該避免可能會封鎖的作業,例如進行鎖定,因為這可能會導致死結或導致系統停止回應。

當服務控制管理員將控制程式代碼傳送至服務時,它會等候處理程式函式傳回,再將其他控制程式碼傳送至其他服務。 控件處理程式應該儘快傳回;如果未在 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)

另請參閱

POWERBROADCAST_SETTING

RegisterDeviceNotification

RegisterServiceCtrlHandlerEx

服務控制處理函式

服務函式

ServiceMain

SetServiceStatus

WM_DEVICECHANGE

WM_POWERBROADCAST

WM_WTSSESSION_CHANGE

WTSSESSION_NOTIFICATION