【windows&flask】flask通过service自动运行

最近在学习在windows平台用flask框架提供Restful API服务,需要使得flask的windows应用能够开机自动运行,并且后台运行,所以通过service来实现。

首先尝试的是在自己派生的serivice类的中直接调用  create_app(debug=True).run(host='0.0.0.0', port=5000) 的方式启动flask。

参考代码:

import win32serviceutil
import win32service
import win32event
import win32evtlogutil
import servicemanager
import socket
import time

import os
import sys
from flask import logging, app, Flask
from run import create_app

sys.path.append(os.path.dirname(__name__))


def main():
    # app.run(host="0.0.0.0", port=5000)  # 服务运行函数
    # launch()
    create_app(debug=True).run(host='0.0.0.0', port=5000)


class MySvc(win32serviceutil.ServiceFramework):
    _svc_name_ = "my web service"  # 服务名
    _svc_display_name_ = "my web service"  # 描述

    def __init__(self, *args):
        win32serviceutil.ServiceFramework.__init__(self, *args)
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
        socket.setdefaulttimeout(5)
        self.stop_requested = False

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)
        self.ReportServiceStatus(win32service.SERVICE_STOPPED)
        # logging.info('Stopped service ...')
        self.stop_requested = True

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

        main()


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

但是启动service的时候一直报错如下,参考了很多种方法一直解决不了

接下来尝试用subprocess的方法拉起进程,成功!

class MyService(PySvc):
    def start(self):
        self.child = subprocess.Popen("python run.py", cwd="C:\\mytest")
        logging.warning('child pid is %s',self.child.pid)
        
    # TODO: add run service code
    def stop(self):
        self.child.kill()
     

但是在stop的发现有一个python进程不能被kill。原因应该是flask本身会启动一个python子进程,相当于subprocess起了一个子进程执行 python run.py,在run.py启动flask的时候又启动了一个子进程,而child.kill只能杀死由subprocess启动的子进程,改成用taskkill就好了。

class MyService(PySvc):
    def start(self):
        self.child = subprocess.Popen("python run.py", cwd="C:\\mytest")
        logging.warning('child pid is %s',self.child.pid)


    # TODO: add run service code
    def stop(self):
        #self.child.kill()
        os.system("taskkill /t /f /pid %s" % self.child.pid)

完整代码如下:

import os
import signal
import subprocess
from time import sleep

import win32service
import win32serviceutil
import win32event
import logging

logging.basicConfig(filename='C:\\app.log', filemode='w', format='%(name)s - %(levelname)s - %(message)s')
logging.warning('This will get logged to a file')


class PySvc(win32serviceutil.ServiceFramework):
    _svc_name_ = "ServicePython"  # NET START/STOP the service by the following name
    _svc_display_name_ = "ServicePython Service"  # name in the Service  Control Manager (SCM)
    _svc_description_ = "This service writes stuff to a file"  # description in the SCM

    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)
        # create an event to listen for stop requests on , 所以也是可以和client进行通信的
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)

    def SvcDoRun(self):  # 启动时调用
        import servicemanager
        self.start()
        win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)

    def SvcStop(self):  # 关闭时调用
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)  # tell the SCM
        win32event.SetEvent(self.hWaitStop)  # fire the stop event
        self.stop()



class MyService(PySvc):
    def start(self):
        self.child = subprocess.Popen("python run.py", cwd="C:\\mytest")
        logging.warning('child pid is %s',self.child.pid)
        


    # TODO: add run service code
    def stop(self):
        os.system("taskkill /t /f /pid %s" % self.child.pid)


# TODO:shut down the running flask web service

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

 

posted @ 2019-09-20 11:08  seyjs  阅读(3729)  评论(0编辑  收藏  举报