用XYNTService把Python程序变为服务
1. XYNTService的使用
1.1. 介绍
通常,NT服务是控制台应用程序,它没有消息循环。不必等到用户登陆电脑,NT服务便能启动,并且在用户登出之后,它也不会停止运行。然而,许多现存的ActiveX控件很难,有时候根本不可能在控制台程序中使用。 可以用Windows程序的形式直接写NT服务,但是XYNTService提供一个更简单的解决方法。本文配套源代码是一个简单的NT服务程序,它能够启动和关闭其它作为服务的程序。所有需要做的是安装这个服务,修改.ini文件。下面是使用XYNTService的好处:
- 它能够启动你指定的任意多个程序。被启动的程序将像 NT 服务一样运行(例如,不用用户登陆机器,它们便会在后台运行)。
- 在没有合适特权情况下,用户不能终止由此服务启动的程序(除非机器关闭)。
- 可以在 NT 服务之外测试和调试你的程序。例如,可以在 DevStudio调试器中运行你的程序,单步进入源代码中查找错误等。当"调试无错"后,你将它配置成产品,从 NT 服务启动它。
1.2. XYNTService
XYNTService.exe是此NT服务程序可执行文件的名字,可以在此下载。
- 为了安装(install)服务,在命令提示符下运行下面命令:XYNTService -i
- 为了卸载(un-install)服务,在命令提示符下运行下面命令:XYNTService -u
默认情况下,在电脑重启时,安装的服务便会自动启动。你也可以使用服务图标从控制面板启动和关闭服务。服务启动时,它将会一个挨一个地创建在XYNTService.ini文件中定义的所有进程。服务关闭时,它将会终止这些进程(以相反顺序)。XYNTService.ini文件应该和可执行文件放在相同的目录。下面是此文件的一个例子。
[Settings]
ServiceName = XYNTService
ProcCount = 3
CheckProcess = 30
[Process0]
CommandLine = c:/MyDir/XYRoot.exe
WorkingDir = c:/MyDir
PauseStart = 1000
PauseEnd = 1000
UserInterface = Yes
Restart = Yes
[Process1]
CommandLine = c:/MyDir/XYDataManager.exe
WorkingDir = c:/MyDir
PauseStart = 1000
PauseEnd = 1000
UserInterface = Yes
Restart = Yes
[Process2]
CommandLine= java XYRoot.XYRoot XYRootJava.ini
UserInterface = No
Restart = No
ServiceName属性指定想要为此NT服务使用的名字,默认名字为XYNTService。如果复制可执行文件和.int文件到不同的目录,在.int文件中修改ServiceName属性,即可安装和配置一个不同的服务。
ProcCount属性指定想要此服务创建的进程的数量。节[Process0]、[Process1]等定义了相关进程的属性。如你所见,此例中要创建3个进程, XYRoot.exe,XYDataManager和java是程序的名称,你可以为每个进程在CommandLine属性指定参数。必须在CommandLine属性为对应进程指定可执行文件的完整路径,除非可执行文件在系统路径。
CheckProcess属性指定是否检查XYNTService启动的进程,也指定了检查的频率。如果此属性的值为0,便不进行检查。如果属性的值为30,则每经30分钟XYNTService将查询操作系统以查看它启动的进程是否还在运行,如果进程的Restart属性值(后门解释)定义为Yes,则将终止的重新启动。此属性的默认值(如果你没有指定它)是60。
WorkingDir属性是当前进程的工作目录。如果你没有指定此属性,当前进程的工作目录将会是X:/winnt/system32。PauseStart属性是服务在启动当前进程后将等待的时间(以毫秒为单位)。在下一个进程需要依靠前一个进程的情况下此选项非常有用。例如,第二个进程不得不连接到第一个进程以便在第一个进程完成初始化后它再运行。如果你没有指定PauseStart属性,默认值将是100毫秒。
当XYNTService关闭时,它将首先向它创建的进程投递WM_QUIT消息,然后调用Win32函数TerminateProcess。PauseEnd属性是服务在调用TerminateProcess之前等待的时间(以毫秒为单位)。此属性可以用来给进程清除和关闭的机会。如果你没有指定PauseEnd属性,默认值将是100毫秒。 UserInterface属性控制一个登陆用户是否能够看到XYNTService创建的进程。然而,仅当XYNTService运行在本地系统帐户下时才起作用,默认就是这样的。在这种情况下,XYNTService创建的进程将不能访问特定用户的设置。你可以配置XYNTService运行在一个用户帐户下,在控制面板中很容易做到这一点(双击服务图标,然后在安装的服务列表中双击XYNTService弹出配置对话框)。
Restart属性用来决定你是否想要XYNTService重新启动终止的进程。如果此属性是No(这是默认值),那么对应进程将不会被重启。如果是Yes,那么终止的进程将会被XYNTService重新启动。启动终止进程的频率由上面的CheckProcess属性指定。
你可以从命令行反弹(停止和重启).int文件中定义的任何进程。例如,如下命令: XYNTService -b 2 将停止和重新启动.ini中[Process2]节定义的进程。 XYNTService也可以用来从命令行启动和停止其它服务。下面是启动(run)和停止(kill)其它服务的命令。 XYNTService -r NameOfServiceToRun XYNTService -k NameOfServiceToKill
特别的,你可以在命令行使用上面的命令启动和停止XYNTService自身。请注意,你不能不带参数启动XYNTService。
运行XYNTService时出现的所有错误都将被写入日志文件,此文件与可执行文件在相同目录下。日志文件中的出错代码是GetLastError API返回的十进制数字,可以在MSDN中查看详细信息。
2. 用XYNTService把Python程序变为服务
经过上面的介绍可以看出XYNTService可以把任何一个可执行程序作为一个服务来启动,所以Python程序当然也可以了。下面给一个简单的例子:
[Settings]
ServiceName=So.net
CheckProcessSeconds = 10
[Process0]
CommandLine = C:/python25/python.exe c:/11.py
WorkingDir= C:/
PauseStart= 1000
PauseEnd= 1000
UserInterface = No
Restart = Yes
安装So.net服务:XYNTService.exe -i。
经过上面配置后,可以在没有登录的时候就可以直接启动So.net服务了,So.net服务会调用c:/11.py程序。并且每10秒检测11.py进程是否激活,如果不活动则重新启动它。