将PHP脚本设置为Windows服务

时间:2011-05-10 15:27:47

标签: php windows windows-services

我需要将PHP脚本设置为Windows服务。

无论登录哪个用户,并且在系统启动时我都需要它运行 - 所以听起来像Windows服务是最好的,但我很高兴听到其他建议。

(这个脚本连续运行,不是“每5分钟运行一次”,我可以使用预定任务管理器。)

http://support.microsoft.com/kb/251192涵盖了使用sc.exe程序安装您的服务。

但是从我读过的内容来看,我需要在PHP脚本周围有一个包装器来接受来自Windows服务管理器的特殊命令。任何人都可以帮忙吗?

7 个答案:

答案 0 :(得分:13)

也许Resource Kit Tools(特别是srvany.exe)可以帮到你。 MSDN:How To Create A User-Defined Service和可能this hint for 2008 Server应该可以帮助您将任何可执行文件设置为服务。 (我已成功在Windows 2003 Server,Windows 2008 Server和Windows XP Professional [其他资源工具包]上使用此功能)

你创建一个包含php your-script.php的bat,用srvany.exe包装它,然后在机器加载服务后启动脚本。

srvany.exe应该处理那些你希望守护进程执行的启动/停止/重启调用。它会在启动时加载你的可执行文件,在停止时终止进程,在重启时执行这两个操作。所以你不必担心这部分。您可能想要检查register_shutdown_function()是否有助于确定服务进程何时被终止。

您甚至可以定义与其他服务的依赖关系(例如某些数据库或某些服务)。

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\THENAMEOFYOURSERVICE]
"DependOnService"="DEPENDONTHIS"

THENAMEOFYOURSERVICE替换为您提供服务的名称,将DEPENDONTHIS替换为要依赖的服务名称(例如“Postgres9.0”或其他内容)。将该文件保存到dependency.reg并使用regedit /s dependency.reg加载。 (或者在资源管理器中双击它...)

答案 1 :(得分:3)

我们使用FireDaemon执行此任务,它不需要包装脚本等。不幸的是,它不是免费软件。

答案 2 :(得分:2)

您可以通过提供不同的参数以及脚本文件作为参数在命令行上运行php。如果您将所需的整行添加到服务配置中,它应该运行。因此,您还可以在创建服务之前尝试该设备。 如果php脚本在你的web路径之外,也许你应该把文件夹添加到PATH-Variable of windows。

答案 3 :(得分:1)

我发现了这个,但我自己没试过。 PHP实际上有一些功能来执行此操作: http://uk.php.net/manual/en/book.win32service.php

以下是一些例子: http://uk.php.net/manual/en/win32service.examples.php

<?php
if ($argv[1] == 'run') {
  win32_start_service_ctrl_dispatcher('dummyphp');

  while (WIN32_SERVICE_CONTROL_STOP != win32_get_last_control_message()) {
    # do your work here.
    # try not to take up more than 30 seconds before going around the loop
    # again
  }
}
?>

答案 4 :(得分:0)

几天后......我找到了这个绝佳的选择!

他构建了一个.exe,它可以恢复服务选项并且工作正常!

https://superuser.com/questions/628176/php-cgi-exe-as-a-windows-service/643676#643676

命令正确:

  

sc create FOO binPath =“service.exe \”C:\ php \ php-cgi.exe -b   127.0.0.1:9000 -c C:\ php \ php.ini“\”type = own start = auto error = ignore DisplayName =“FOO php”

答案 5 :(得分:0)

NSSM - the Non-Sucking Service Manager也是一种解决方案,然后

nssm install PHP php-cgi.exe -b 127.0.0.1:9000 -c C:\php\php.ini

答案 6 :(得分:0)

在外壳中循环。

  1. 在php循环中添加循环计数器,并在小时后退出以重启进程。
  2. 内存使用控制
  3. 每100秒重新连接到数据库

Shell脚本执行简单的循环,每个循环都创建新的日志文件

PHP和shell脚本:

    ini_set('memory_limit', '300M');
    $loopCnt = 0;
    while(true) {
        /**
         * Maximal time limit for loop execution
         */
        set_time_limit(10);

        $loopCnt ++;
        /**
         * each hour finishing
         */
        if($loopCnt > 60 * 60){
            exit;
        }
        usleep(self::SLEEP_MICROSECONDS);
        if ($loopCnt % 60 === 0) { //log every 60 seconds memory usage
            $this->out('memory usage: '.memory_get_usage());
            //reconnect DB to avoid timeouts and server gone away errors
            Yii::$app->db->close();
            Yii::$app->db->open();
        }
        if (memory_get_usage() > self::MEMORY_LIMIT) {
            $this->out('memory limit reached: '.self::MEMORY_LIMIT . ' actual:  ' . memory_get_usage() . ' exit');
            exit;
        }
        
        /**
        *  do work
        */

    }

}

//蝙蝠文件

 set loopcount=1000000

 :loop

     echo Loop %DATE% %TIME% %loopcount%

     set t=%TIME: =0%

     php cwbouncer.php > C:\logs\cwbouncer_%DATE:~2,2%%DATE:~5,2%%DATE:~8,2%_%t:~0,2%%t:~3,2%%t:~6,2%.log

    set /a loopcount=loopcount-1

    if %loopcount%==0 goto exitloop

    goto loop

:exitloop