【发布时间】:2019-09-04 17:25:49
【问题描述】:
我正在尝试让Flask 应用程序在 Windows 中作为服务运行。我已经尝试按照here 和here 的建议实施解决方案,但没有成功。
我有一个只有两个文件的简单文件夹:
Project
|
+-- myapp.py
+-- win32_service.py
myapp.py 内部是一个简单的Flask 应用程序:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
以及服务框架win32_service.py:
import win32serviceutil
import win32service
import win32event
import win32evtlogutil
import servicemanager
import socket
import time
import logging
import os
import sys
sys.path.append(os.path.dirname(__name__))
from myapp import app
logging.basicConfig(
filename = r'c:\tmp\flask-service.log',
level = logging.DEBUG,
format = '[flaskapp] %(levelname)-7.7s %(message)s'
)
class HelloFlaskSvc (win32serviceutil.ServiceFramework):
_svc_name_ = "FlaskApp"
_svc_display_name_ = "FlaskApp 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_,'')
)
self.main()
def main(self):
app.run(host="127.0.0.1", port=8000)
if __name__ == '__main__':
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(HelloFlaskSvc)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(HelloFlaskSvc)
然后我使用以下命令通过pyinstaller 将其编译为exe 文件:
pyinstaller --onefile --hidden-import win32timezone win32_service.py
我得到编译成功的exe。然后我继续注册服务(以管理员权限打开 cmd):
>>> win32_service.exe install
> Installing service FlaskApp
> Service installed
我尝试启动它:
>>> win32_service.exe start
> Starting service FlaskApp
然后什么都没有发生(没有错误)。此外,如果我尝试从任务管理器启动它,它会将状态更改为Starting,然后更改为Stopped。
这些是安装在 virtualenv 中的模块:
altgraph==0.16.1
Click==7.0
Flask==1.0.2
future==0.17.1
itsdangerous==1.1.0
Jinja2==2.10.1
macholib==1.11
MarkupSafe==1.1.1
pefile==2018.8.8
PyInstaller==3.4
pyodbc==4.0.26
pywin32==224
pywin32-ctypes==0.2.0
Werkzeug==0.15.2
系统规格:
Python - 3.6.5
OS - Windows 10
我在这里缺少什么?任何帮助表示赞赏。
编辑
Windows EventViewer 显示错误:
The description for Event ID 3 from source FlaskApp cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer.
If the event originated on another computer, the display information had to be saved with the event.
The following information was included with the event:
Traceback (most recent call last):
File "lib\site-packages\win32\lib\win32serviceutil.py", line 839, in SvcRun
File "win32_service.py", line 47, in SvcDoRun
File "win32_service.py", line 50, in main
File "lib\site-packages\flask\app.py", line 938, in run
File "lib\site-packages\flask\cli.py", line 629, in show_server_banner
File "lib\site-packages\click\utils.py", line 260, in echo
SystemError: <built-in method replace of str object at 0x000001E36AD465D0> returned a result with an error set
编辑 2
如果我使用单个spec 文件,隐藏导入找不到某些模块(这是pyinstaller 的输出:
4972 INFO: Analyzing hidden import 'ClickFlask'
4973 ERROR: Hidden import 'ClickFlask' not found
4974 INFO: Analyzing hidden import 'future'
4981 INFO: Analyzing hidden import 'itsdangerous'
5029 INFO: Analyzing hidden import 'Jinja2'
5030 ERROR: Hidden import 'Jinja2' not found
5030 INFO: Analyzing hidden import 'MarkupSafe'
5032 ERROR: Hidden import 'MarkupSafe' not found
5033 INFO: Analyzing hidden import 'pyodbc'
5034 INFO: Analyzing hidden import 'pywin32'
5035 ERROR: Hidden import 'pywin32' not found
5035 INFO: Analyzing hidden import 'pywin32-ctypes'
5036 ERROR: Hidden import 'pywin32-ctypes' not found
会不会跟这个有关?为什么有些模块可以找到而有些没有?我正在使用 virtualenv。
【问题讨论】:
-
它是否在 EventViewer 中记录事件?您在那里看到任何有用的信息吗?
-
@amanb 感谢您指出这一点。是的,将使用 EventViewer 中的错误进行更新。
-
您如何将两个文件中的代码合并到一个 Python 脚本中,然后尝试看看它是否有效。稍后,它们可以分成单独的脚本。这个SO answer 可能会有所帮助。
-
不走运,如果我只使用一个 Python 脚本,我也会遇到同样的错误。
-
好的,我会在我的 Windows 机器上测试它并分享我的结果
标签: python python-3.x flask pyinstaller pywin32