[An example of how to create a Windows service. Evaluate code first and use at your own risk!]
<?php
//No timeouts, Flush Content immediatly
set_time_limit(0);
ob_implicit_flush();
//Service Settings
$phpPath = "D:\\php\\php5.2.9";
$ServiceName = 'phpServiceName';
$ServiceDisplay = 'phpDisplayName';
//Windows Service Control
$ServiceAction = "status";
//$ServiceAction = "debug";
if ( isset($_GET['ServiceAction']) and strlen($_GET['ServiceAction']) ) {
$ServiceAction = addslashes($_GET['ServiceAction']);
} else if ( isset($argv) and isset($argv[1]) and strlen($argv[1]) ) {
$ServiceAction = $argv[1];
}
if( $ServiceAction == "status" ) {
$ServiceStatus = win32_query_service_status($ServiceName);
if ( $ServiceStatus['CurrentState'] == WIN32_SERVICE_STOPPED ) {
echo "Service Stopped\n\n";
} else if ( $ServiceStatus['CurrentState'] == WIN32_SERVICE_START_PENDING ) {
echo "Service Start Pending\n\n";
} else if ( $ServiceStatus['CurrentState'] == WIN32_SERVICE_STOP_PENDING ) {
echo "Service Stop Pending\n\n";
} else if ( $ServiceStatus['CurrentState'] == WIN32_SERVICE_RUNNING ) {
echo "Service Running\n\n";
} else if ( $ServiceStatus['CurrentState'] == WIN32_SERVICE_CONTINUE_PENDING ) {
echo "Service Continue Pending\n\n";
} else if ( $ServiceStatus['CurrentState'] == WIN32_SERVICE_PAUSE_PENDING ) {
echo "Service Pause Pending\n\n";
} else if ( $ServiceStatus['CurrentState'] == WIN32_SERVICE_PAUSED ) {
echo "Service Paused\n\n";
} else{
echo "Service Unknown\n\n";
}
exit;
} else if ( $ServiceAction == "install" ) {
//Install Windows Service
win32_create_service( Array(
'service' => $ServiceName,
'display' => $ServiceDisplay,
'params' => __FILE__ . " run",
'path' => $phpPath."\\php.exe",
));
echo "Service Installed\n\n";
exit;
} else if ( $ServiceAction == "uninstall" ) {
//Remove Windows Service
win32_delete_service($ServiceName);
echo "Service Removed\n\n";
exit;
} else if( $ServiceAction == "start") {
//Start Windows Service
win32_start_service($ServiceName);
echo "Service Started\n\n";
exit;
} else if( $ServiceAction == "stop" ) {
//Stop Windows Service
win32_stop_service($ServiceName);
echo "Service Stopped\n\n";
exit;
} else if ( $ServiceAction == "run" ) {
//Run Windows Service
win32_start_service_ctrl_dispatcher($ServiceName);
win32_set_service_status(WIN32_SERVICE_RUNNING);
} else if ( $ServiceAction == "debug" ) {
//Debug Windows Service
set_time_limit(10);
} else {
exit();
}
//Server Loop
while (1) {
//Handle Windows Service Request
usleep(100*1000);
if ( $ServiceAction == "run" ) {
switch ( win32_get_last_control_message() ) {
case WIN32_SERVICE_CONTROL_CONTINUE:
break;
case WIN32_SERVICE_CONTROL_INTERROGATE:
win32_set_service_status(WIN32_NO_ERROR);
break;
case WIN32_SERVICE_CONTROL_STOP:
win32_set_service_status(WIN32_SERVICE_STOPPED);
exit;
default:
win32_set_service_status(WIN32_ERROR_CALL_NOT_IMPLEMENTED);
}
}
//User Loop
sleep(1);
echo "\n<BR>YOUR CODE HERE";
}
//Exit
if ( $ServiceAction == "run" ) {
win32_set_service_status(WIN32_SERVICE_STOPPED);
}
exit();
?>
win32_create_service
(PECL win32service SVN)
win32_create_service — SCM データベースに新しいサービスのエントリを作成する
説明
パラメータ
- details
-
サービスの詳細情報を含む配列。
- service
-
サービスの短い名前。net コマンドでサービスを 制御する際に、この名前を使用します。この名前は一意である(同名の サービスが 2 つ存在することがない)必要があり、スペースを含む 名前は可能な限り避けるべきです。
- display
-
サービスの表示名。これは、サービスアプレットに表示される名前です。
- description
-
サービスの長い名前。これは「サービス」アプレットで表示される名前です。
- user
-
サービスを実行するユーザ名。指定しなかった場合、サービスは LocalSystem アカウントで実行されます。ユーザ名が指定された場合、 password も指定する必要があります。
- password
-
user に対応するパスワード。
- path
-
サービスの開始時に起動される実行モジュールのフルパス。 指定しなかった場合、現在の PHP プロセスへのパスが使用されます。
- params
-
サービスの開始時に渡されるコマンドラインパラメータ。 PHP スクリプトをサービスとして実行したい場合は、最初のパラメータは 実行するスクリプトへのフルパスとなります。 スクリプト名やパスにスペースを含む場合は、PHP スクリプトへのフルパスを " で囲まなければなりません。
- load_order
-
load_order を制御します。現時点では完全にはサポートされていません。
- svc_type
-
サービスの型を指定します。指定しなかった場合、デフォルト値は WIN32_SERVICE_WIN32_OWN_PROCESS です。 よくわからない場合はこの値を変更しないでください。
- start_type
-
サービスをどのように開始させるかを指定します。デフォルトは WIN32_SERVICE_AUTO_START で、これは マシンの起動時にサービスを開始させることを意味します。
- error_control
-
サービスに問題が発生した際にとるべき行動を SCM に指示します。 デフォルトは WIN32_SERVER_ERROR_IGNORE です。 この値を変更することは、現時点では完全にはサポートされていません。
- delayed_start
-
delayed_start を TRUE にすると、 他の自動起動サービスが開始したあとで少し間をおいてサービスが起動するようになります。
任意のサービスに対してこれを指定することができますが、そのサービスの start_type が WIN32_SERVICE_AUTO_START でない場合は何の効果も及ぼしません。
この設定が使えるのは、Windows Vista および Windows Server 2008 以降のみです。
- base_priority
-
プロセッサの使用状況への影響を考慮すると、 ベース優先度は通常より低めに設定しておかなければなりません。
base_priority には、 Win32 ベース優先度クラス で定義された定数のいずれかを設定します。
- machine
-
オプションで、サービスを作成したいマシン名を指定します。 指定しなかった場合は、ローカルマシンを使用します。
返り値
成功した場合に WIN32_NO_ERROR を返します。パラメータに問題がある場合は FALSE、失敗した場合は Win32 エラーコード を返します。
例
例1 win32_create_service() の例
'dummyphp' というショートネームのサービスを作ります。
<?php
$x = win32_create_service(array(
'service' => 'dummyphp', # サービスの名前
'display' => 'sample dummy PHP service', # 短い説明
'description' => 'This is a dummy Windows service created using PHP.', # 長い説明
'params' => '"' . __FILE__ . '" run', # スクリプトへのパスとパラメータ
));
debug_zval_dump($x);
?>
Other start_type values:
0x00000002: A service started automatically by the service control manager during system startup. For more information, see Automatically Starting Services.
0x00000000: A device driver started by the system loader. This value is valid only for driver services.
0x00000003: A service started by the service control manager when a process calls the win32_start_service() function.
0x00000004: A service that cannot be started. Attempts to start the service result in the error code
0x00000001: A device driver started by the IoInitSystem function. This value is valid only for driver services.
I can confirm that 0x00000003 works as expected (service is created, but must be started manually).
More here:
http://msdn2.microsoft.com/en-us/library/ms682450.aspx
