首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在PyInstaller上使用--onefile选项捆绑CEFpython

在PyInstaller上使用--onefile选项捆绑CEFpython
EN

Stack Overflow用户
提问于 2018-07-27 20:51:50
回答 2查看 1.6K关注 0票数 2

我有一个应用程序,我有两个可执行文件: Flask-SocketIO-Server和CefPython浏览器。我将这两个可执行文件与PyInstaller捆绑在一起。带有-- The文件选项的Flask-Server和带有--onedir选项的cefpython,因为我不能使用-- the文件。现在我决定只有两个代码(Flask和CEFpython)的可执行文件,这样我的flask服务器就有了运行CEF图形用户界面的代码:

代码语言:javascript
复制
if __name__ == '__main__':

    if len(sys.argv) > 1 and sys.argv[1] == 'dev':
        print "Running Flask-SocketIO on dev mode"
    else:
        print "Running Flask-SocketIO on production mode"
        path = os.getcwd()
        gui_path = path + '\\display_react\\display_react.exe'
        print 'Running Graphical User Interface...'
        thread.start_new_thread(display_react.main, ())  # Baterias
        print 'Initializing server'


    socketio.run(app, debug=False)

代码运行良好,但当我尝试使用--onefile选项将此代码与PyInstaller捆绑在一起时,生成的可执行文件无法工作,这会导致一些CEF依赖。下面是运行Pyinstaller时的错误:

在生产模式下运行Flask-SocketIO运行图形用户界面...初始化服务器wxpython.py CEF Python 57.1 wxpython.py Python 2.7.14 64位wxpython.py wxPython 4.0.1 msw (phoenix) 0727/125110.576:错误:main_Delegate.cc(684)无法加载en-US 0727/125110.576的区域设置包:错误:main_Delegate.cc(691)无法加载cef.pak 0727/125110.578:错误:main_Delegate.cc(708)无法加载cef_100_percent.pak 0727/125110.582:错误:Main_delegate.cc( 20418 )无法加载cef_200_percent.pak 0727/ 125110.582:错误:main_Delegate.cc(726)无法加载cef_extensions.pak 0727/125110.648:错误:content_Client.cc(269)没有可用于id 20418 0727/125110.648的数据资源:错误:content_Client.cc(269)没有可用于id 20419 0727/125110.650的数据资源:错误:content_Client.cc(269)没有id 0727可用的数据资源/125110.655:ERROR:content_client.cc(269)没有可用于id 20421 0727/125110.656的数据资源:错误:content_client.cc(269)没有可用于id 20422 0727/125110.656的数据资源:错误:content_Client.cc(269)没有可用于id 20417 0727/125110.680的数据资源:错误: extension _system.cc(72)无法解析扩展清单。C:\Users\Ricardo\AppData\Local\Temp_MEI95~1\display_react.py:118: wxPyDeprecationWarning:调用已弃用的项EmptyIcon。改用:class:Icon

下面是我使用的.spec文件:

代码语言:javascript
复制
# -*- mode: python -*-

block_cipher = None

def get_cefpython_path():
    import cefpython3 as cefpython

    path = os.path.dirname(cefpython.__file__)
    return "%s%s" % (path, os.sep)

cefp = get_cefpython_path()


a = Analysis(['server.py'],
             pathex=['C:\\Users\\Ricardo\\addvolt-scanning-tool\\backend'],
             binaries=[],
             datas=[('PCANBasic.dll', '.'), ('o.ico', '.')], #some dlls i need for flask
             hiddenimports=['engineio.async_gevent'], #engineio hidden import for Flask usage
             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,
          a.binaries,
          a.zipfiles,
          a.datas + [('locales/en-US.pak', '%s/locales/en-US.pak' % cefp, 'DATA')], # my try to fix that missing dependencies
          name='server',
          debug=False,
          strip=False,
          upx=True,
          runtime_tmpdir=None,
          console=True )

编辑:已解决

多亏了@cztomczak,我让它正常工作了。问题不是在PyInstaller上,而是在wxpython.py寻找语言环境、资源和子进程的过程中。尽管所有文件都在“temp/dir/_MEIxxx”中,但wxpython在可执行文件的目录中查找这些文件。所以我通知代码在临时目录中查找这些文件的方法是:

代码语言:javascript
复制
dir_temp = tempfile.gettempdir()
files = []
for i in os.listdir(dir_temp):
    if os.path.isdir(os.path.join(dir_temp,i)) and '_MEI' in i:
        files.append(i)
dir_temp = dir_temp + str(files[0])
dir_temp = os.path.join(dir_temp, str(files[0]))
dir_temp_locale = os.path.join(dir_temp, 'locales')
dir_temp_subprocess = os.path.join(dir_temp_subprocess, 'subprocess.exe')

print dir_temp
dir_temp = dir_temp.replace("\\", "\\\\")
print dir_temp
print dir_temp_locale
dir_temp_locale = dir_temp_locale.replace("\\", "\\\\")
print dir_temp_locale
dir_temp_supbprocess = dir_temp_subprocess.replace("\\", "\\\\")
print dir_temp_subprocess

..。

代码语言:javascript
复制
settings = {'auto_zooming': '-2.5', 'locales_dir_path': dir_temp_locale, 'resources_dir_path': dir_temp, 'browser_subprocess_path': dir_temp_subprocess}

我必须这样做,因为在temp (_MEIxxxx)上创建的文件夹的名称总是在变化。将来我可能会遇到问题,因为如果应用程序崩溃,_MEIxx文件夹将不会被删除,如果我尝试重新运行可执行文件,这段代码将有两个_MEI文件夹,并且可能根本不会工作,直到有人清理临时目录。

所以,继续...要将应用程序捆绑到一个文件中:-在Python27/envs/libs/site-package/Pyinstaller/hooks上粘贴钩子-cefpython3.py(在包中提供)-运行Pyinstaller --使用--onefile选项-告诉cefpython代码区域设置、资源和子进程的位置(locale_dir_path、resource_dir_path、browser_subprocess_path)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-07-28 03:10:58

我猜你得到的错误是因为你的spec文件没有包含所有必需的CEF二进制文件。有一个官方的pyinstaller示例,您可以使用和修改它来使用--onefile选项:https://github.com/cztomczak/cefpython/blob/master/examples/pyinstaller/README-pyinstaller.md

票数 1
EN

Stack Overflow用户

发布于 2019-02-25 14:41:28

我也遇到过类似的问题,我发现使用_MEIPASS环境变量是一个更优雅的解决方案。

代码语言:javascript
复制
import cefpython
import os
import sys

if hasattr(sys, '_MEIPASS'):
    # settings when packaged
    settings = {'locales_dir_path': os.path.join(sys._MEIPASS, 'locales'),
                'resources_dir_path': sys._MEIPASS,
                'browser_subprocess_path': os.path.join(sys._MEIPASS, 'subprocess.exe'),
                'log_file': os.path.join(sys._MEIPASS, 'debug.log')}
else:
    # settings when unpackaged
    settings = {}

cefPython.Initialize(settings=settings)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51558349

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档