Skip to content

PyWebIO不能直接在Windows服务中调用 #669

@cute-omega

Description

@cute-omega

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
 

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions