扩展php_win32service安装服务,但服务无法启动(挂起)

时间:2013-03-13 10:42:56

标签: php windows windows-services

我正在尝试在Windows Server 2008 SP1计算机上设置PHP Web应用程序。我们已在Windows Server 2003上正确运行此应用程序,但现在无法正常启动php_win32service PHP扩展程序构建的Windows服务。

以下是PHP代码的相关部分。以下是安装和卸载的部分:

if ($argv[1] == 'install') {
    win32_create_service(array(
        'service' => $service_name,
        'display' => $service_name,
        'params' => '"'. __FILE__ . '"' . ' run'));
        exit;
} 
else if ($argv[1] == 'uninstall') {
    win32_delete_service($service_name);
    exit;
} 
else if ($argv[1] != 'run') {
   die("Invalid arguments");
}

win32_start_service_ctrl_dispatcher($service_name);

这是主循环:

while (1) {
    switch (win32_get_last_control_message()) {
       case WIN32_SERVICE_CONTROL_INTERROGATE: win32_set_service_status(WIN32_SERVICE_RUNNING); break; // Respond with status
       case WIN32_SERVICE_CONTROL_STOP: win32_set_service_status(WIN32_SERVICE_STOPPED);  exit; // Terminate script
    }         
    processQueue();
    usleep(500000);
}

只要我以管理员身份运行cmd,安装和卸载就会起作用。如果我在用于登录服务器的帐户下启动cmd,则不会创建服务win32_create_service。我也可以使用命令行中的run参数运行脚本并且它正确运行,但是当我尝试启动服务时,它只会挂起Starting消息并且永远不会进入{{1}国家。

我认为此问题与计算机上Started帐户的权限有关,但我不知道需要哪些权限才能使其正常运行。我也不知道如何调试这个并找出LocalSystem发生了什么错误/问题,特别是因为我没有权利在此服务器上更改安全设置。我需要对安全设置进行的任何更改,我需要与网络管理员进行通信,以便他可以执行更改。任何人都可以提供调试或解决此问题的任何帮助吗?

更新:

此问题似乎只发生在64位版本的WIN32_SERVICE_CONTROL_INTERROGATE中。在尝试启动服务时,PHP的64位编译似乎遇到了某种问题。我删除了64位版本的php_win32service和' php_win32service'并用32位版本替换它们。然后该服务正确启动。

2 个答案:

答案 0 :(得分:1)

您是否尝试过使用NetworkService帐户?其他方式是创建自己的服务帐户。你在服务器外面沟通吗?也许防火墙?

聚苯乙烯。网络服务帐户具有默认密码(系统已知)

请注意,此帐户没有密码,因此您在此次调用中提供的所有密码信息都会被忽略。

http://msdn.microsoft.com/nl-nl/library/windows/desktop/ms684272(v=vs.85).aspx

答案 1 :(得分:0)

更新的答案:

我现在确信,当您将PHP更新或降级到其他版本时,会出现此问题,但无法使用php_win32service删除并重新创建新安装的{{1}版本的服务}}。这在我的旧答案中被提到了,但是在另一台服务器上遇到同样的事情并通过删除和重新创建服务条目来解决它之后,我确信这是这个问题的真正原因,这不是一个错误。 PHP

旧答案:

当我尝试将PHP计算机上的PHPWindows Server 2008更新为5.3时,我再次遇到此问题。从我所做的测试中我得出结论,5.6扩展名适用于php_win32service.dll,但不适用于PHP 5.3以上。从5.4开始,似乎存在一个错误,即函数5.4总是返回0而不是有效状态。

我终于知道了在这里发布的帖子发生了什么: http://enlinea.creaelicita.cl/guia/function.win32-set-service-status.html

所以,如果你有这样的代码:

win32_get_last_control_message

然后

while (1) {
    switch (win32_get_last_control_message()) {
        case WIN32_SERVICE_CONTROL_INTERROGATE: win32_set_service_status(WIN32_SERVICE_RUNNING); break; // Respond with status
        case WIN32_SERVICE_CONTROL_STOP: win32_set_service_status(WIN32_SERVICE_STOPPED); exit; // Terminate script
    }    
    usleep(3000000);

    // Main script goes here
    processQueue();
}
永远不会调用

,因为win32_set_service_status(WIN32_SERVICE_RUNNING); 永远不会得到值4(WIN32_SERVICE_CONTROL_INTERROGATE)。

我使用的解决方法是将默认大小写添加到设置服务状态的switch语句中。像这样:

win32_get_last_control_message

顺便说一句,我还发现如果我升级到 switch (win32_get_last_control_message()) { case WIN32_SERVICE_CONTROL_INTERROGATE: win32_set_service_status(WIN32_SERVICE_RUNNING); 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_SERVICE_RUNNING); } 并且在尝试启动它们之前没有重新创建服务条目,则会出现此问题。因此,除了应用上述解决方法之外,请记住先卸载有问题的Windows服务,然后从PHP 5.4脚本重新安装。