PHP Conference Japan 2024

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

服务定期递增的检查点值,用于在冗长的启动、停止、暂停或继续操作期间报告其进度。例如,在启动时,服务应在完成每个初始化步骤时递增此值。

statusWIN32_SERVICE_STOP_PENDINGWIN32_SERVICE_START_PENDINGWIN32_SERVICE_CONTINUE_PENDINGWIN32_SERVICE_PAUSE_PENDING之一时,checkpoint才有效。

返回值

不返回任何值。

在1.0.0版本之前,成功时返回WIN32_NO_ERROR,如果参数有問題或失败时返回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中有效。

参见

添加注释

用户贡献的注释 2 条注释

m dot hald at surfto dot ch
16 年前
在我的机器(Win XP SP2)上,“win32_get_last_control_message”函数从未返回4,所以我必须也回复0。

最后,在混合了几个例子之后,我现在有一个无需在我的事件日志中填写错误的工作版本。

<?php

/*
* PHP 示例模板
*/

/*
* 应用主函数
* 上次函数执行结束后每秒钟调用一次
* 执行时间不应超过 20 秒
* 否则,你应该至少每 20 秒调用一次 NTServiceResponder();
* 警告:如果存在停止请求,NTServiceResponder 将退出;
*/
function Service_Main()
{
// 你的应用程序代码在此处 !!!
sleep(1); // 模拟操作
}

/********************************************************************
*
* 服务控制
*
********************************************************************/

$SERVICE_NAME = "phptestservice";
$SERVICE_DISPLAY = "使用 PHP 的测试服务";

// 因此你可以获取:$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(
"此应用程序需要作为服务安装。\n 使用参数 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(
"参数错误,需要作为服务运行");
}

// 连接到服务调度程序并通知启动成功
if (!win32_start_service_ctrl_dispatcher($SERVICE_NAME)) die('无法连接到服务:'.$SERVICE_NAME);
win32_set_service_status(WIN32_SERVICE_RUNNING);

// 主服务器循环
while (1)
{
NTServiceResponder();

// 主要脚本在此处执行
Service_Main();

sleep(1); // 每个循环至少延迟 1 秒
}
win32_set_service_status(WIN32_SERVICE_STOPPED);

/*
* 响应 NTServiceRequests
*/
function NTServiceResponder()
{

switch (
win32_get_last_control_message())
{
case
0: // 修补程序:似乎从未转到 4 (WIN32_SERVICE_CONTROL_INTERROGATE)
win32_set_service_status(WIN32_SERVICE_RUNNING);
return
TRUE;
break;
case
WIN32_SERVICE_CONTROL_CONTINUE:
return
TRUE; // "继续"
case WIN32_SERVICE_CONTROL_INTERROGATE:
win32_set_service_status(WIN32_SERVICE_RUNNING);
return
TRUE; // 以状态响应
case WIN32_SERVICE_CONTROL_STOP:
win32_set_service_status(WIN32_SERVICE_STOPPED);
exit;
// 终止脚本
default:
win32_set_service_status(WIN32_ERROR_CALL_NOT_IMPLEMENTED); // 添加更多情况以处理其他服务调用
}

return
FALSE;
}

?>
[email protected]
14 年前
经过大量的搜索,我最终找到了所有能够创建一个工作的 Windows 服务和服务器的组件,包括
- 安装和卸载服务
- 启动和停止服务
- 实际运行一个基本的服务器
- 响应 Windows 服务的停止/启动/重启请求

我希望您觉得这有用!我使用 PHP 5.2 和 5.2 的 PECL 库完成了这项工作(当时 PHP 5.3 没有为其编译的 PECL 库)

<?php
// 服务设置
$Service = 'MyServiceFinal';
$Display = '我的PHP服务';

// 服务器设置
$host = '127.0.0.1'; // 绑定到IP #
$port = 23; // 端口 #
$max = 20; // 最大客户端数


// 如果没有启动参数,则退出
if (!isset($argv[1])){ShowHelp(); exit;}

// 创建Windows服务
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
"服务已安装\n\n";
exit;

// 删除Windows服务
} else if ($argv[1] == 'uninstall') {
$x = win32_delete_service($Service);
debug_zval_dump($x);
echo
"服务已删除\n\n";
exit;

// 启动Windows服务
} elseif($argv[1] == "start") {
$x = win32_start_service($Service);
debug_zval_dump($x);
echo
"服务已启动\n\n";
exit;

// 停止Windows服务
} elseif($argv[1] == "stop") {
$x = win32_stop_service($Service);
debug_zval_dump($x);
echo
"服务已停止\n\n";
exit;

// 未知命令
} else if ($argv[1] != 'run') {
ShowHelp(); exit();
}

// 通知Windows服务已启动…
if (!win32_start_service_ctrl_dispatcher($Service)) die("无法连接到服务:$Service");
win32_set_service_status(WIN32_SERVICE_RUNNING);

// 无超时,立即刷新内容
set_time_limit(0);
ob_implicit_flush();

// 服务器循环
while (1) {
usleep(500);

// 处理Windows服务请求
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); // 添加更多情况以处理其他服务调用
}
// 实际服务器代码

}

// 清理并退出
win32_set_service_status(WIN32_SERVICE_STOPPED);
exit;

//*************** 函数 ***************
function ShowHelp(){
echo
"使用方法:
install:\t 安装服务
uninstall:\t 删除服务
start:\t\t 启动Windows服务
stop:\t\t 停止Windows服务
run:\t\t 由CMS调用以运行服务

有关代码编号的信息,请键入“net helpmsg xxxx”
示例:“net helpmsg 1072”

"
;
}
?>
To Top