如何在 Windows 中将 Python 脚本作为服务运行?

新手上路,请多包涵

我正在为一组程序绘制架构草图,这些程序共享存储在数据库中的各种相互关联的对象。我希望其中一个程序充当服务,为这些对象的操作提供更高级别的接口,而其他程序则通过该服务访问对象。

我目前的目标是将 Python 和 Django 框架作为实现该服务的技术。我很确定我想出了如何在 Linux 中守护 Python 程序。但是,系统应该支持 Windows 是一个可选的规范项目。我对 Windows 编程没有什么经验,对 Windows 服务也没有任何经验。

是否可以将 Python 程序作为 Windows 服务运行(即无需用户登录即可自动运行)? 我不一定要实现这部分,但我需要大致了解如何完成,以便决定是否按照这些思路进行设计。

编辑:感谢到目前为止的所有答案,它们非常全面。我还想知道一件事: Windows 如何知道我的服务?我可以使用本机 Windows 实用程序管理它吗? 将启动/停止脚本放入 /etc/init.d 有什么等价物?

原文由 Hanno Fietz 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
2 个回答

是的你可以。我使用 ActivePython 附带的 pythoncom 库来执行此操作,或者可以使用 pywin32 (Windows 扩展的 Python)安装。

这是一个简单服务的基本框架:

 import win32serviceutil
import win32service
import win32event
import servicemanager
import socket

class AppServerSvc (win32serviceutil.ServiceFramework):
    _svc_name_ = "TestService"
    _svc_display_name_ = "Test Service"

    def __init__(self,args):
        win32serviceutil.ServiceFramework.__init__(self,args)
        self.hWaitStop = win32event.CreateEvent(None,0,0,None)
        socket.setdefaulttimeout(60)

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)

    def SvcDoRun(self):
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                              servicemanager.PYS_SERVICE_STARTED,
                              (self._svc_name_,''))
        self.main()

    def main(self):
        pass

if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(AppServerSvc)

您的代码将进入 main() 方法——通常带有某种无限循环,可能会通过检查标志来中断,该标志是您在 SvcStop 方法中设置的

原文由 Ricardo Reyes 发布,翻译遵循 CC BY-SA 3.0 许可协议

最简单的方法是使用: NSSM - Non-Sucking Service Manager。 只需下载并解压缩到您选择的位置。它是一个独立的实用程序,大约 300KB(比为此目的安装整个 pywin32 套件要少得多)并且不需要“安装”。该 zip 包含该实用程序的 64 位和 32 位版本。两者都应该在当前系统上运行良好(您可以使用 32 位版本来管理 64 位系统上的服务)。

图形界面方法

1 - 将 python 程序安装为服务。以管理员身份打开 Win 提示符

c:\>nssm.exe install WinService

2 - 在 NSSM 的 GUI 控制台上:

路径:C:\Python27\Python27.exe

启动目录:C:\Python27

参数:c:\WinService.py

3 - 检查 services.msc 上创建的服务

脚本方法(无 GUI)

如果您的服务应该是自动化的、非交互式过程的一部分,这可能是您无法控制的,例如批处理或安装程序脚本,这将很方便。假设这些命令是以管理权限执行的。

为方便起见,此处通过简单地将实用程序称为 nssm.exe 来描述命令。但是,建议在脚本中使用其完整路径 c:\path\to\nssm.exe 更明确地引用它,因为它是一个独立的可执行文件,可能位于系统不知道的私有路径中。

1.安装服务

您必须指定服务的名称、正确的 Python 可执行文件的路径以及脚本的路径:

 nssm.exe install ProjectService "c:\path\to\python.exe" "c:\path\to\project\app\main.py"

更明确地说:

 nssm.exe install ProjectService
nssm.exe set ProjectService Application "c:\path\to\python.exe"
nssm.exe set ProjectService AppParameters "c:\path\to\project\app\main.py"

或者,您可能希望您的 Python 应用程序作为 Python 模块启动。一种简单的方法是告诉 nssm 它需要更改到正确的起始目录,就像您从命令 shell 启动时自己做的那样:

 nssm.exe install ProjectService "c:\path\to\python.exe" "-m app.main"
nssm.exe set ProjectService AppDirectory "c:\path\to\project"

这种方法适用于虚拟环境和自包含(嵌入式)Python 安装。只需确保使用常用方法正确解决了这些环境中的任何路径问题即可。 nssm 可以根据需要设置环境变量(例如 PYTHONPATH),还可以启动批处理脚本。

2.启动服务

nssm.exe start ProjectService

3.停止服务

nssm.exe stop ProjectService

4.删除服务 指定 confirm 参数跳过交互确认。

 nssm.exe remove ProjectService confirm

原文由 Adriano P 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题