CakeFest 2024: The Official CakePHP Conference

win32_set_service_status

(PECL win32service >=0.1.0)

win32_set_service_statusサービスの状態を更新する

説明

win32_set_service_status(int $status, int $checkpoint = 0): void

SCM に、実行中のサービスの現在の状態を通知します。 この関数のコールは、現在実行中のサービスについてのみ有効です。

警告

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

パラメータ

status

以下のステータスコードのうちのひとつ。 WIN32_SERVICE_RUNNINGWIN32_SERVICE_STOPPEDWIN32_SERVICE_STOP_PENDINGWIN32_SERVICE_START_PENDINGWIN32_SERVICE_CONTINUE_PENDINGWIN32_SERVICE_PAUSE_PENDINGWIN32_SERVICE_PAUSED

checkpoint

start, stop, pause や continue の操作がとても時間がかかる場合に、 その状態を報告する目的で定期的にインクリメントされるチェックポイントの値。 たとえば、サービスが起動中の場合は、 初期化のステップがひとつ終了するたびに、 この値をインクリメントすべきです。

checkpoint の値は、 status が以下の場合のみ、正しい値です: WIN32_SERVICE_STOP_PENDING, WIN32_SERVICE_START_PENDING, WIN32_SERVICE_CONTINUE_PENDING, WIN32_SERVICE_PAUSE_PENDING.

戻り値

値を返しません。

バージョン 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.2.0 この関数は、"cli" SAPI でのみ動作するようになりました。

参考

add a note

User Contributed Notes 2 notes

up
3
m dot hald at surfto dot ch
15 years ago
On my Machine (Win XP SP2) the function "win32_get_last_control_message" never returns 4 so i will have to reply to 0 also.

finally after mixing several examples i now have a version working woithout filling my event log with errors:

<?php

/*
* PHP SAMPLE TEMPLATE
*/

/*
* APP MAIN FUNCTION
* Called each second after the function last time finished
* Should not take longer than max 20 seconds to execute
* ELSE you should call NTServiceResponder(); at least each 20 secs
* WARNING: NTServiceResponder will exit; if there was a STOP request
*/
function Service_Main()
{
// YOU APPLICATION CODE HERE !!!
sleep(1); // dummy something
}

/********************************************************************
*
* SERVICE CONTROLLING
*
********************************************************************/

$SERVICE_NAME = "phptestservice";
$SERVICE_DISPLAY = "Test Service with PHP";

// so u can get: $SERVICE_PATH_PARTS["dirname"] $SERVICE_PATH_PARTS["basename"] $SERVICE_PATH_PARTS["extension"]
$SERVICE_PATH_PARTS = pathinfo(__FILE__);

$SERVICE_PARAMS = " run";

if (!isset(
$argv[1]))
{
die(
"this application need to be installed as a service.\n run with param install");
}

if (
$argv[1] == 'install')
{
$x = win32_create_service(array(
'service' => $SERVICE_NAME,
'display' => $SERVICE_DISPLAY,
'params' => __FILE__ . $SERVICE_PARAMS,
//'path' => $SERVICE_PATH_PARTS["dirname"] . '\php.exe'
));
debug_zval_dump($x);
exit;
}
else if (
$argv[1] == 'uninstall')
{
$x = win32_delete_service('dummyphp');
debug_zval_dump($x);
exit;
}
else if (
$argv[1] != 'run')
{
die(
"bogus args, needs to run as service");
}

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

// Main Server Loop
while (1)
{
NTServiceResponder();

// Main script goes here
Service_Main();

sleep(1); // at least 1 sec delay per loop
}
win32_set_service_status(WIN32_SERVICE_STOPPED);

/*
* Response to NTServiceRequests
*/
function NTServiceResponder()
{

switch (
win32_get_last_control_message())
{
case
0: // PATCH for: seems never to go to 4 (WIN32_SERVICE_CONTROL_INTERROGATE)
win32_set_service_status(WIN32_SERVICE_RUNNING);
return
TRUE;
break;
case
WIN32_SERVICE_CONTROL_CONTINUE:
return
TRUE; // "Continue"
case WIN32_SERVICE_CONTROL_INTERROGATE:
win32_set_service_status(WIN32_SERVICE_RUNNING);
return
TRUE; // 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
}

return
FALSE;
}

?>
up
-1
paul_nelson57071 at yahoo dot com
13 years ago
So after much searching I finally found all the peices to make a working windows service & server including:
- Installing & Uninstalling the service
- Starting & Stopping the Service
- Actually running a basic Server
- Responding to windows Service to Stop/Start/Restart

I hope you find this useful! I did this using PHP 5.2 and the PECL library for 5.2 (PHP 5.3 at the time does not have a PECL Library compiled for it)

<?php
//Service Settings
$Service = 'MyServiceFinal';
$Display = 'My PHP Service';

//Server Settings
$host = '127.0.0.1'; //Bind to IP #
$port = 23; //On port #
$max = 20; //Maximum Clients


//Exit if no start-up argument is passed
if (!isset($argv[1])){ShowHelp(); exit;}

//Create Windows Service
if ($argv[1] == 'install') {
$x = win32_create_service(array(
'service' => $Service,
'display' => $Service,
'params' => __file__ . ' run',
'path' => 'c:\\php\\php.exe',
));
debug_zval_dump($x);
echo
"Service Installed\n\n";
exit;

//Remove Windows Service
} else if ($argv[1] == 'uninstall') {
$x = win32_delete_service($Service);
debug_zval_dump($x);
echo
"Service Removed\n\n";
exit;

//Start Windows Service
} elseif($argv[1] == "start") {
$x = win32_start_service($Service);
debug_zval_dump($x);
echo
"Service Started\n\n";
exit;

//Stop Windows Service
} elseif($argv[1] == "stop") {
$x = win32_stop_service($Service);
debug_zval_dump($x);
echo
"Service Stopped\n\n";
exit;

//Unkown Command
} else if ($argv[1] != 'run') {
ShowHelp(); exit();
}

//Tell windows the service has started...
if (!win32_start_service_ctrl_dispatcher($Service)) die("Could not connect to service : $Service");
win32_set_service_status(WIN32_SERVICE_RUNNING);

// No timeouts, flush content immediatly
set_time_limit(0);
ob_implicit_flush();

//Server Loop
while (1) {
usleep(500);

//Handle Windows Service Request
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
}
//Acutal Server Code

}

//Clean up and Exit
win32_set_service_status(WIN32_SERVICE_STOPPED);
exit;

//*************** FUNCTIONS ***************
function ShowHelp(){
echo
"Usage:
install:\t installs servce
uninstall:\t deletes service
start:\t\t Start the windows service
stop:\t\t Stops the windows service
run:\t\t called by CMS to run the service

For information on code numbers type 'net helpmsg xxxx'
EXAMPEL: 'net helpmsg 1072'

"
;
}
?>
To Top