pyinstaller:确定 Windows 服务中 socket.io 和 aiohttp 的隐藏导入

Posted

技术标签:

【中文标题】pyinstaller:确定 Windows 服务中 socket.io 和 aiohttp 的隐藏导入【英文标题】:pyinstaller: Determine hidden imports for socket.io and aiohttp in Windows Service 【发布时间】:2018-08-21 18:10:34 【问题描述】:

我一直在使用 python 构建一个运行 socket.io 和 aiohttp 的 Windows 服务。该程序在解释器中完美运行,但是一旦我使用 pyinstaller 将其打包成 exe 文件,代码就会失败并出现异常:

Traceback (most recent call last):
  File "autocoreserver.py", line 24, in __init__
  File "site-packages\socketio\asyncio_server.py", line 67, in __init__
  File "site-packages\socketio\server.py", line 89, in __init__
  File "site-packages\engineio\server.py", line 123, in __init__
ValueError: Invalid async_mode specified

在我的程序中,当它尝试创建 AsyncServer 时抛出异常(文件“autocoreserver.py”,第 24 行,在 init 中)。

try:
    self.sio = socketio.AsyncServer()
except:
    rootLogger.exception("AsyncServer init")

我在网上进行了研究,知道这是一个常见问题,通常使用 spec 文件中的 hiddenimports 参数来解决。但是,在添加了我可以在网上找到的所有建议后,错误并没有改变。

为了尝试查找缺少的模块,我使用“-v”选项构建了 exe。然而,列出了几十个模块,几乎没有一个与socket.io或aiohttp有关。例如,缺少许多 Qt 模块,但这是一个没有用户界面的服务,我没有使用 Qt。

为了确定我需要的实际模块列表,我将这段代码添加到我的程序中,它列出了所有正在使用的模块并将它们写到一个文件中。

    f = open('c:\\modulereport.log','w')
    f.write('hiddenimports=[\n')

    mods = [m.__name__ for m in sys.modules.values() if m]

    for m in mods:
        f.write( '    \'0\',\n'.format(m) )

    f.write("],")

    f.close()

这给了我一份程序应该使用的每个模块的列表,但它缺少几个。当我添加回我知道丢失的所有模块时,我又回到了同样的错误。

我是 pyinstaller 和 python 的新手,我猜有更好的方法来查明缺失的模块。谁能告诉我找到我缺少的模块的最佳方法?

这是我的规范文件(build.spec):

# -*- mode: python -*-

block_cipher = None

#options = [ ('v', None, 'OPTION') ]
options = []

a = Analysis(['autocoreservice.py'],
             pathex=['C:\\Users\\ThomasBitskyJr\\Documents\\srcroot\\3182TeeTable\\AutoCore-Server'],
             binaries=[],
             datas=[],
             hiddenimports=[
                'win32timezone',
                'engineio.async_gevent',
                'gevent',
                'gevent-websocket',
                'aiohttp'
             ],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          options,
          a.binaries,
          a.zipfiles,
          a.datas,
          name='autocoreservice',
          debug=False,
          strip=False,
          upx=True,
          runtime_tmpdir=None,
          console=True )

我使用以下命令构建 exe:

pyinstaller --onefile build.spec

版本信息:

python --version
Python 3.6.5 :: Anaconda, Inc.
pip --version
pip 18.0 from c:\users\thomasbitskyjr\anaconda3\lib\site-packages\pip (python 3.6)
pyinstaller --version
3.3.1

提前感谢您的任何建议。

更新:我通过更新系统上的所有模块来改善这种情况。这将错误移到了过程的后期。现在我明白了:

Traceback (most recent call last):
  File "C:\Users\User\Documents\srcroot\autocoreserver.py", line 30, in __init__
    self.sio.attach(self.app)
  File "C:\Users\User\Anaconda3\lib\site-packages\socketio\asyncio_server.py", line 74, in attach
    self.eio.attach(app, socketio_path)
  File "C:\Users\User\Anaconda3\lib\site-packages\engineio\asyncio_server.py", line 64, in attach
    self._async['create_route'](app, self, '//'.format(engineio_path))
KeyError: 'create_route'

我已经尝试过 pyinstaller 和 cx_Freeze 并得到相同的结果。

【问题讨论】:

【参考方案1】:

我没有任何好的故障排除技巧,但我能够解决这个确切的错误。我的研究主要表明问题是由于隐藏的进口,但找到隐藏的东西是一种猜测和检查。因为它是发生错误的引擎,所以我在站点包中进行了一些窥探以查看包目录设置的样子,并提出了以下命令,并带有包含丢失包的标志

pyinstaller <your_script>.py --hidden-import engineio.async_drivers.aiohttp --hidden-import engineio.async_aiohttp  --distpath some/dist/dir

【讨论】:

作为一个魅力!赞一个!

以上是关于pyinstaller:确定 Windows 服务中 socket.io 和 aiohttp 的隐藏导入的主要内容,如果未能解决你的问题,请参考以下文章

Pyinstaller .exe 抛出 Windows Defender [无发布者]

Python使用WMI模块获取Windows系统的硬件信息,并使用pyinstaller库编译打包成exe的可执行文件

windows下手动安装pyinstaller(python2.7)

如何从我的 kivy 应用程序(Pyinstaller)获取 Windows 可执行文件?

windows pyinstaller 安装时显示没有pythonxx.DLL/Pyinstaller:FormatMessageW failed/ xxx module 找不到

PyInstaller 构建的 Windows EXE 因多处理而失败