Open
Description
BUG描述
在Python中编写Windows服务的一般方法是继承win32serviceutil.ServiceFramework
类并实现__init__(self, args), SvcDoRun(self), SvcStop(self)
方法与_svc_name_:str, _svc_display_name_:str, _svc_description_:str
属性,然后在__main__中注册该服务类并等待Windows调用。
但我在SvcDoRun()
中尝试使用pywebio.start_server()
时却在【计算机管理/事件查看器/Windows日志/应用程序】中发现如下错误信息:
The instance's SvcRun() method failed
Traceback (most recent call last):
File "C:\Users\Nobody\miniconda3\Lib\site-packages\win32\lib\win32serviceutil.py", line 1071, in SvcRun
self.SvcDoRun()
File "C:\Users\Nobody\Desktop\Programs\Projects\Python\wifi-test\python_winsvc.py", line 111, in SvcDoRun
WirelessNetworkMonitor.main()
File "C:\Users\Nobody\Desktop\Programs\Projects\Python\wifi-test\WirelessNetworkMonitor.py", line 237, in main
start_server(scan, debug=config["debug"], port=config["port"])
File "C:\Users\Nobody\miniconda3\Lib\site-packages\pywebio\platform\tornado.py", line 273, in start_server
set_ioloop(tornado.ioloop.IOLoop.current()) # to enable bokeh app
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Nobody\miniconda3\Lib\site-packages\tornado\ioloop.py", line 274, in current
loop = asyncio.get_event_loop()
^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Nobody\miniconda3\Lib\asyncio\events.py", line 699, in get_event_loop
self.set_event_loop(self.new_event_loop())
^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Nobody\miniconda3\Lib\asyncio\events.py", line 720, in new_event_loop
return self._loop_factory()
^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Nobody\miniconda3\Lib\asyncio\windows_events.py", line 316, in __init__
super().__init__(proactor)
File "C:\Users\Nobody\miniconda3\Lib\asyncio\proactor_events.py", line 643, in __init__
signal.set_wakeup_fd(self._csock.fileno())
ValueError: set_wakeup_fd only works in main thread of the main interpreter
显然问题出在pywebio库中(我的代码中没有使用多线程)。这里也不是User's guide中提到的没有使用register_thread(thread)
的问题(显然程序没有像文档所示的那样报pywebio.exceptions.SessionNotFoundException
异常)
这恐怕是一个严重(虽然不常见,毕竟目前没有看到同样在Windows服务中使用PyWebIO的issue)且麻烦的bug,天知道为什么这个bug从asyncio波及到tornado再到pywebio。如果可以的话我希望先得到一个可用的缓解措施。(我尝试用其他后端框架再试一遍)
改用flask,报错:
The instance's SvcRun() method failed
Traceback (most recent call last):
File "C:\Users\Nobody\miniconda3\Lib\site-packages\win32\lib\win32serviceutil.py", line 1071, in SvcRun
self.SvcDoRun()
File "C:\Users\Nobody\Desktop\Programs\Projects\Python\wifi-test\python_winsvc.py", line 111, in SvcDoRun
WirelessNetworkMonitor.main()
File "C:\Users\Nobody\Desktop\Programs\Projects\Python\wifi-test\WirelessNetworkMonitor.py", line 237, in main
start_server(scan, debug=config["debug"], port=config["port"])
File "C:\Users\Nobody\miniconda3\Lib\site-packages\pywebio\platform\flask.py", line 181, in start_server
app.run(host=host, port=port, debug=debug, threaded=True, use_evalex=False, **flask_options)
File "C:\Users\Nobody\miniconda3\Lib\site-packages\flask\app.py", line 662, in run
run_simple(t.cast(str, host), port, self, **options)
File "C:\Users\Nobody\miniconda3\Lib\site-packages\werkzeug\serving.py", line 1115, in run_simple
run_with_reloader(
File "C:\Users\Nobody\miniconda3\Lib\site-packages\werkzeug\_reloader.py", line 452, in run_with_reloader
signal.signal(signal.SIGTERM, lambda *args: sys.exit(0))
File "C:\Users\Nobody\miniconda3\Lib\signal.py", line 58, in signal
handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: signal only works in main thread of the main interpreter
改用django,报错
The instance's SvcRun() method failed
Traceback (most recent call last):
File "C:\Users\Nobody\miniconda3\Lib\site-packages\win32\lib\win32serviceutil.py", line 1071, in SvcRun
self.SvcDoRun()
File "C:\Users\Nobody\Desktop\Programs\Projects\Python\wifi-test\python_winsvc.py", line 111, in SvcDoRun
WirelessNetworkMonitor.main()
File "C:\Users\Nobody\Desktop\Programs\Projects\Python\wifi-test\WirelessNetworkMonitor.py", line 237, in main
start_server(scan, debug=config["debug"], port=config["port"])
File "C:\Users\Nobody\miniconda3\Lib\site-packages\pywebio\platform\django.py", line 214, in start_server
http_server.listen(port, address=host)
File "C:\Users\Nobody\miniconda3\Lib\site-packages\tornado\tcpserver.py", line 191, in listen
self.add_sockets(sockets)
File "C:\Users\Nobody\miniconda3\Lib\site-packages\tornado\tcpserver.py", line 204, in add_sockets
self._handlers[sock.fileno()] = add_accept_handler(
^^^^^^^^^^^^^^^^^^^
File "C:\Users\Nobody\miniconda3\Lib\site-packages\tornado\netutil.py", line 247, in add_accept_handler
io_loop = IOLoop.current()
^^^^^^^^^^^^^^^^
File "C:\Users\Nobody\miniconda3\Lib\site-packages\tornado\ioloop.py", line 274, in current
loop = asyncio.get_event_loop()
^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Nobody\miniconda3\Lib\asyncio\events.py", line 699, in get_event_loop
self.set_event_loop(self.new_event_loop())
^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Nobody\miniconda3\Lib\asyncio\events.py", line 720, in new_event_loop
return self._loop_factory()
^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Nobody\miniconda3\Lib\asyncio\windows_events.py", line 316, in __init__
super().__init__(proactor)
File "C:\Users\Nobody\miniconda3\Lib\asyncio\proactor_events.py", line 643, in __init__
signal.set_wakeup_fd(self._csock.fileno())
ValueError: set_wakeup_fd only works in main thread of the main interpreter
改用aiohttp报错
The instance's SvcRun() method failed
Traceback (most recent call last):
File "C:\Users\Nobody\miniconda3\Lib\site-packages\win32\lib\win32serviceutil.py", line 1071, in SvcRun
self.SvcDoRun()
File "C:\Users\Nobody\Desktop\Programs\Projects\Python\wifi-test\python_winsvc.py", line 111, in SvcDoRun
WirelessNetworkMonitor.main()
File "C:\Users\Nobody\Desktop\Programs\Projects\Python\wifi-test\WirelessNetworkMonitor.py", line 237, in main
start_server(scan, debug=config["debug"], port=config["port"])
File "C:\Users\Nobody\miniconda3\Lib\site-packages\pywebio\platform\aiohttp.py", line 222, in start_server
web.run_app(app, host=host, port=port)
File "C:\Users\Nobody\miniconda3\Lib\site-packages\aiohttp\web.py", line 486, in run_app
loop = asyncio.new_event_loop()
^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Nobody\miniconda3\Lib\asyncio\events.py", line 823, in new_event_loop
return get_event_loop_policy().new_event_loop()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Nobody\miniconda3\Lib\asyncio\events.py", line 720, in new_event_loop
return self._loop_factory()
^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Nobody\miniconda3\Lib\asyncio\windows_events.py", line 316, in __init__
super().__init__(proactor)
File "C:\Users\Nobody\miniconda3\Lib\asyncio\proactor_events.py", line 643, in __init__
signal.set_wakeup_fd(self._csock.fileno())
ValueError: set_wakeup_fd only works in main thread of the main interpreter
改用fastapi报错
The instance's SvcRun() method failed
Traceback (most recent call last):
File "C:\Users\Nobody\miniconda3\Lib\site-packages\win32\lib\win32serviceutil.py", line 1071, in SvcRun
self.SvcDoRun()
File "C:\Users\Nobody\Desktop\Programs\Projects\Python\wifi-test\python_winsvc.py", line 111, in SvcDoRun
WirelessNetworkMonitor.main()
File "C:\Users\Nobody\Desktop\Programs\Projects\Python\wifi-test\WirelessNetworkMonitor.py", line 237, in main
start_server(scan, debug=config["debug"], port=config["port"])
File "C:\Users\Nobody\miniconda3\Lib\site-packages\pywebio\platform\fastapi.py", line 187, in start_server
uvicorn.run(app, host=host, port=port, **uvicorn_settings)
File "C:\Users\Nobody\miniconda3\Lib\site-packages\uvicorn\main.py", line 516, in run
config = Config(
^^^^^^^
File "C:\Users\Nobody\miniconda3\Lib\site-packages\uvicorn\config.py", line 273, in __init__
self.configure_logging()
File "C:\Users\Nobody\miniconda3\Lib\site-packages\uvicorn\config.py", line 365, in configure_logging
logging.config.dictConfig(self.log_config)
File "C:\Users\Nobody\miniconda3\Lib\logging\config.py", line 914, in dictConfig
dictConfigClass(config).configure()
File "C:\Users\Nobody\miniconda3\Lib\logging\config.py", line 563, in configure
raise ValueError('Unable to configure '
ValueError: Unable to configure formatter 'default'
环境信息
- 操作系统及版本: Microsoft Windows 11 x86-64 24H2 (OS内部版本26100.2454)
- 浏览器及版本: 【与问题无关】
- Python版本: Python 3.12.3
- 库版本(由conda export导出): ```yaml
name: base
channels: - https://mirrors.sjtug.sjtu.edu.cn/anaconda/cloud/conda-forge
- conda-forge
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/pro
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
- defaults
- https://repo.anaconda.com/pkgs/main
- https://repo.anaconda.com/pkgs/r
- https://repo.anaconda.com/pkgs/msys2
dependencies: - aiofiles=24.1.0=pyhd8ed1ab_1
- aiohappyeyeballs=2.4.4=pyhd8ed1ab_1
- aiohttp=3.11.10=py312h31fea79_0
- aiosignal=1.3.1=pyhd8ed1ab_1
- anaconda-anon-usage=0.4.4=py312hfc23b7f_100
- anaconda_powershell_prompt=1.1.0=haa95532_0
- anaconda_prompt=1.1.0=haa95532_0
- annotated-types=0.7.0=pyhd8ed1ab_1
- anyio=4.7.0=pyhd8ed1ab_0
- archspec=0.2.3=pyhd3eb1b0_0
- asgiref=3.8.1=pyhd8ed1ab_1
- attrs=24.2.0=pyh71513ae_1
- blinker=1.9.0=pyhff2d567_0
- boltons=23.0.0=py312haa95532_0
- brotli-python=1.0.9=py312hd77b12b_8
- bzip2=1.0.8=h2bbff1b_6
- ca-certificates=2024.9.24=haa95532_0
- certifi=2024.8.30=pyhd8ed1ab_0
- cffi=1.17.1=py312h827c3e9_0
- charset-normalizer=3.3.2=pyhd3eb1b0_0
- click=8.1.7=win_pyh7428d3b_1
- colorama=0.4.6=py312haa95532_0
- conda=24.11.0=py312h2e8e312_0
- conda-content-trust=0.2.0=py312haa95532_1
- conda-libmamba-solver=24.9.0=pyhd3eb1b0_0
- conda-package-handling=2.3.0=py312haa95532_0
- conda-package-streaming=0.10.0=py312haa95532_0
- cryptography=43.0.0=py312h89fc84f_0
- distro=1.9.0=py312haa95532_0
- django=5.1.4=pyhd8ed1ab_0
- dnspython=2.7.0=pyhff2d567_1
- email-validator=2.2.0=pyhd8ed1ab_1
- email_validator=2.2.0=hd8ed1ab_1
- et_xmlfile=2.0.0=pyhd8ed1ab_1
- exceptiongroup=1.2.2=pyhd8ed1ab_1
- expat=2.6.3=h5da7b33_0
- fastapi=0.115.6=pyhd8ed1ab_0
- fastapi-cli=0.0.6=pyhd8ed1ab_0
- flask=3.1.0=pyhff2d567_0
- fmt=9.1.0=h6d14046_1
- frozendict=2.4.2=py312haa95532_0
- frozenlist=1.5.0=py312h4389bb4_0
- h11=0.14.0=pyhd8ed1ab_1
- h2=4.1.0=pyhd8ed1ab_1
- hpack=4.0.0=pyhd8ed1ab_1
- httpcore=1.0.7=pyh29332c3_1
- httptools=0.6.4=py312h4389bb4_0
- httpx=0.28.1=pyhd8ed1ab_0
- hyperframe=6.0.1=pyhd8ed1ab_1
- idna=3.7=py312haa95532_0
- importlib-metadata=8.5.0=pyha770c72_1
- itsdangerous=2.2.0=pyhd8ed1ab_1
- jinja2=3.1.4=pyhd8ed1ab_1
- jsonpatch=1.33=py312haa95532_1
- jsonpointer=2.1=pyhd3eb1b0_0
- libarchive=3.7.4=h9243413_0
- libcurl=8.9.1=h0416ee5_0
- libexpat=2.6.3=he0c23c2_0
- libffi=3.4.4=hd77b12b_1
- libiconv=1.16=h2bbff1b_3
- libmamba=1.5.8=h99b1521_3
- libmambapy=1.5.8=py312h77c03ed_3
- libsolv=0.7.24=h23ce68f_1
- libsqlite=3.47.2=h67fdade_0
- libssh2=1.11.0=h291bd65_0
- libxml2=2.13.1=h24da03e_2
- libzlib=1.2.13=h2466b09_6
- lz4-c=1.9.4=h2bbff1b_1
- markdown-it-py=3.0.0=pyhd8ed1ab_1
- markupsafe=3.0.2=py312h31fea79_1
- mdurl=0.1.2=pyhd8ed1ab_1
- menuinst=2.1.2=py312h5da7b33_0
- multidict=6.1.0=py312h31fea79_1
- openpyxl=3.1.5=py312he70551f_1
- openssl=3.4.0=h2466b09_0
- packaging=24.1=py312haa95532_0
- pcre2=10.42=h0ff8eda_1
- pip=24.2=py312haa95532_0
- platformdirs=3.10.0=py312haa95532_0
- pluggy=1.0.0=py312haa95532_1
- propcache=0.2.1=py312h4389bb4_0
- pybind11-abi=5=hd3eb1b0_0
- pycosat=0.6.6=py312h2bbff1b_1
- pycparser=2.21=pyhd3eb1b0_0
- pydantic=2.10.3=pyh3cfb1c2_0
- pydantic-core=2.27.1=py312h2615798_0
- pygments=2.18.0=pyhd8ed1ab_1
- pysocks=1.7.1=py312haa95532_0
- python=3.12.3=h2628c8c_0_cpython
- python-dotenv=1.0.1=pyhd8ed1ab_1
- python-multipart=0.0.19=pyhff2d567_1
- python_abi=3.12=5_cp312
- pywin32=307=py312h275cf98_3
- pyyaml=6.0.2=py312h4389bb4_1
- reproc=14.2.4=hd77b12b_2
- reproc-cpp=14.2.4=hd77b12b_2
- requests=2.32.3=pyhd8ed1ab_1
- rich=13.9.4=pyhd8ed1ab_1
- rich-toolkit=0.11.3=pyh29332c3_0
- ruamel.yaml=0.18.6=py312h827c3e9_0
- ruamel.yaml.clib=0.2.8=py312h827c3e9_0
- setuptools=75.1.0=py312haa95532_0
- shellingham=1.5.4=pyhd8ed1ab_1
- sniffio=1.3.1=pyhd8ed1ab_1
- sqlite=3.45.3=h2bbff1b_0
- sqlparse=0.5.2=pyhd8ed1ab_1
- starlette=0.41.3=pyha770c72_1
- tk=8.6.14=h0416ee5_0
- tornado=6.4.2=py312h4389bb4_0
- tqdm=4.66.5=py312hfc267ef_0
- truststore=0.8.0=py312haa95532_0
- typer=0.15.1=pyhd8ed1ab_0
- typer-slim=0.15.1=pyhd8ed1ab_0
- typer-slim-standard=0.15.1=hd8ed1ab_0
- typing-extensions=4.12.2=hd8ed1ab_1
- typing_extensions=4.12.2=pyha770c72_1
- tzdata=2024b=h04d1e81_0
- ucrt=10.0.22621.0=h57928b3_1
- urllib3=2.2.3=py312haa95532_0
- uvicorn=0.32.1=pyh5737063_1
- uvicorn-standard=0.32.1=h5737063_1
- vc=14.40=h2eaa2aa_1
- vc14_runtime=14.42.34433=he29a5d6_23
- vs2015_runtime=14.42.34433=hdffcdeb_23
- watchfiles=1.0.0=py312h2615798_0
- websockets=14.1=py312h4389bb4_0
- werkzeug=3.1.3=pyhd8ed1ab_1
- wheel=0.44.0=py312haa95532_0
- win_inet_pton=1.1.0=py312haa95532_0
- xz=5.4.6=h8cc25b3_1
- yaml=0.2.5=h8ffe710_2
- yaml-cpp=0.8.0=hd77b12b_1
- yarl=1.18.3=py312h4389bb4_0
- zipp=3.21.0=pyhd8ed1ab_1
- zlib=1.2.13=h2466b09_6
- zstandard=0.23.0=py312h4fc1ca9_0
- zstd=1.5.6=h8880b57_0
- pip:
- pywebio==1.8.3
- ua-parser==1.0.0
- ua-parser-builtins==0.18.0.post1
- user-agents==2.2.0
- wxpusher==2.3.0
prefix: C:\Users\Nobody\miniconda3