PHP Conference Nagoya 2025

win32_start_service_ctrl_dispatcher

(PECL win32service >=0.1.0)

win32_start_service_ctrl_dispatcher スクリプトを SCM に登録し、指定した名前でサービスとして稼動させる ようにする

説明

win32_start_service_ctrl_dispatcher(string $name, bool $gracefulMode = true): void

サービスコントロールマネージャ経由で起動させる際、サービスプロセスは 「チェックイン」を要求され、これによってサービスのモニタリングや 通信の機能を確立します。この関数は、サービスコントロールマネージャとの 低レベル通信を処理するスレッドを生成し、チェックインを実行します。

サービスが開始したら、サービスプロセスで行わなければならないことは次のふたつです。 まず最初は、サービスが実行中であることをサービスコントロールマネージャに通知することです。 これは、win32_set_service_status() に定数 WIN32_SERVICE_RUNNING を指定してコールすれば実現できます。 サービスが実際に動き出すまでに何らかの長い処理を要する場合は、定数 WIN32_SERVICE_START_PENDING を使うこともできます。 もうひとつは、常にサービスコントロールマネージャにチェックインし続け、 サービスをいつ終了させるべきかを確認することです。 これは、定期的に win32_get_last_control_message() をコールして戻り値を適切に処理することで実現できます。

警告

0.2.0 以降では、この関数は "cli" SAPI でのみ動作します。 他の SAPI では、この関数は無効になっています。

パラメータ

name

サービスの短い名前。win32_create_service() で登録されたもの。

gracefulMode

true の場合、graceful に終了します。 false の場合、エラーで終了します。 詳細は win32_set_service_exit_mode() を参照ください。

戻り値

値を返しません。

バージョン 1.0.0 より前では、成功した場合に WIN32_NO_ERROR を返していました。パラメータに問題がある場合は false、失敗した場合は Win32 エラーコード を返します。

エラー / 例外

バージョン 1.0.0 より前では、 SAPI が "cli" でない場合、 この関数は E_ERROR レベルのエラーを発生させていました。

バージョン 1.0.0 以降では、 SAPI が "cli" でない場合、 Win32ServiceException がスローされます。

変更履歴

バージョン 説明
PECL win32service 1.0.0 引数に不正な値があった場合、 ValueError をスローするようになりました。 これより前のバージョンでは、false を返していました。
PECL win32service 1.0.0 エラー時に Win32ServiceException をスローするようになりました。 これより前のバージョンでは、 Win32 エラーコード を返していました。
PECL win32service 1.0.0 戻り値の型が void になりました。 これより前のバージョンでは、mixed でした。
PECL win32service 0.4.0 gracefulMode パラメータが追加されました。
PECL win32service 0.2.0 この関数は "cli" SAPI でのみ動作するようになりました。

例1 win32_start_service_ctrl_dispatcher() の例

サービスが SCM で実行されているかどうかを調べます。

<?php
if (!win32_start_service_ctrl_dispatcher('dummyphp')) {
die(
"I'm probably not running under the service control manager");
}

win32_set_service_status(WIN32_SERVICE_START_PENDING);

// このサービスを処理するための、何らかの長い処理をします

win32_set_service_status(WIN32_SERVICE_RUNNING);

while (
WIN32_SERVICE_CONTROL_STOP != win32_get_last_control_message()) {
# ここでなんらかの処理をします。1 回のループに 30 秒以上かからない
# ように心がけてください。
}
?>

参考

add a note

User Contributed Notes 3 notes

up
0
andrea
15 years ago
Insert value of params between " if the string have a space:

<?php
// First you need to create a service, you only need to do this once
/*
win32_create_service(array(
'service' => 'myphpservice',
'display' => 'My PHP Service',
'params' => '"c:\\my folder\myphpservice.php"',
'path' => 'c:\\PHP\\php.exe'));
*/
?>
up
-1
dylan at nopower dot org
17 years ago
<?php
// First you need to create a service, you only need to do this once
/*
win32_create_service(array(
'service' => 'myphpservice',
'display' => 'My PHP Service',
'params' => 'c:\\myphpservice.php',
'path' => 'c:\\PHP\\php.exe'));
*/

$myservicename = 'myphpservice';

// Connect to service dispatcher and notify that startup was successful
if (!win32_start_service_ctrl_dispatcher($myservicename)) die('Could not connect to service :'.$myservicename);
win32_set_service_status(WIN32_SERVICE_RUNNING);

// Main Server Loop
while (1) {
switch (
win32_get_last_control_message()) {
case
WIN32_SERVICE_CONTROL_CONTINUE: break; // Continue server routine
case WIN32_SERVICE_CONTROL_INTERROGATE: win32_set_service_status(WIN32_NO_ERROR); break; // Respond with status
case WIN32_SERVICE_CONTROL_STOP: win32_set_service_status(WIN32_SERVICE_STOPPED); exit; // Terminate script
default: win32_set_service_status(WIN32_ERROR_CALL_NOT_IMPLEMENTED); // Add more cases to handle other service calls
}

// Main script goes here

sleep(10); // Run every 10 seconds
}
win32_set_service_status(WIN32_SERVICE_STOPPED);
?>
up
-2
Guibod
17 years ago
Don't try to call "win32_start_service_ctrl_dispatcher" too late in your code. You'd trigger a #2186 error : "The service is not responding to the control function." (from commande line) or a #1053 error : "The service did not respond to the start or control request in a timely fashion." (from services GUI).

Try not to load a bunch of PEAR classes before to register php script as Service like I did.

Another good hint, to get a verbose version of the return code, you can call "NET HELPMSG ###" from command line where ### is your error code.
To Top