我已经设法拼凑了一个 pywin32 Windows 服务在 pylons 服务员 wsgi 服务器(下)内运行烧瓶的工作演示。一个侄女自给自足的解决方案就是这个想法。
我花了几个小时来审查和测试让女服务员干净地退出的方法(比如这个和这个),但到目前为止我能做的最好的是一种自杀式的 SIGINT,它让 Windows 在通过服务控制停止时抱怨“管道已结束”面板,但至少它停止了:-/我猜 pywin32 启动的 pythonservice.exe 不应该终止,只是女服务员踩踏?
老实说,我仍然不确定这是关于女服务员、pywin32 还是只是普通的 python 的问题。我确实感觉答案就在我面前,但现在我完全被难住了。
欢迎任何建议!
import os
import random
import signal
import socket
from flask import Flask, escape, request
import servicemanager
import win32event
import win32service
import win32serviceutil
from waitress import serve
app = Flask(__name__)
@app.route('/')
def hello():
random.seed()
x = random.randint(1, 1000000)
name = request.args.get("name", "World")
return 'Hello, %s! - %s - %s' % (escape(name), x, os.getpid())
# based on https://www.thepythoncorner.com/2018/08/how-to-create-a-windows-service-in-python/
class SMWinservice(win32serviceutil.ServiceFramework):
'''Base class to create winservice in Python'''
_svc_name_ = 'WaitressService'
_svc_display_name_ = 'Waitress server'
_svc_description_ = 'Python waitress WSGI service'
@classmethod
def parse_command_line(cls):
'''
ClassMethod to parse the command line
'''
win32serviceutil.HandleCommandLine(cls)
def __init__(self, args):
'''
Constructor of the winservice
'''
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
socket.setdefaulttimeout(60)
def SvcStop(self):
'''
Called when the service is asked to stop
'''
self.stop()
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STOPPED,
(self._svc_name_, ''))
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
'''
Called when the service is asked to start
'''
self.start()
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
self.main()
def start(self):
pass
def stop(self):
print 'sigint'
os.kill(os.getpid(), signal.SIGINT)
def main(self):
print 'serve'
serve(app, listen='*:5000')
if __name__ == '__main__':
SMWinservice.parse_command_line()