PyInstaller example - onefile executable file

2,323 views
Skip to first unread message

srig...@gmail.com

unread,
May 18, 2018, 7:01:01 AM5/18/18
to CEF Python
I am trying to create a single executable file using the CEFpython PyInstaller example. I am not getting the single executable file after the below changes.

sub = Popen(["pyinstaller", "--clean", "-F", "--windowed", "pyinstaller.spec"], env=env)

I don't want the entire folder and its dependency files. I need single exe file for my python script. Any suggestions please let me know.

Czarek Tomczak

unread,
May 22, 2018, 11:34:17 AM5/22/18
to CEF Python
I think you will need to make changes to pyinstaller.spec file, as it overwrites some settings. Best to ask on pyinstaller forums.

srig...@gmail.com

unread,
May 31, 2018, 1:43:44 AM5/31/18
to CEF Python
Thanks Czarek.

I am able to generate single exe file based on the below changes in the pyinstaller.spec.

****************************************************************************

# -*- mode: python -*-
# -*- coding: utf-8 -*-

"""
This is a PyInstaller spec file.
"""

import os
from PyInstaller.building.api import PYZ, EXE, COLLECT
from PyInstaller.building.build_main import Analysis
from PyInstaller.utils.hooks import is_module_satisfies

cipher_obj = None

a = Analysis(
["qt.py"],
hookspath=["."], # To find "hook-cefpython3.py"
pathex=['E:\\Sriram\\learning\\python\\browser\\examples\\pyinstaller',],
cipher=cipher_obj,
win_private_assemblies=True,
win_no_prefer_redirects=True,
)


pyz = PYZ(a.pure,
a.zipped_data,
cipher=cipher_obj)

exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
name='cefapp',
debug=True,
strip=False,
upx=False,
console=True,
icon="../resources/wxpython.ico" )

***************************************************************************

I also made few modification qt.py to use the pyside as the default. I have also moved the qt.py file inside the pyinstaller folder. When I run using the python command, it is working fine. But when I run the exe I am getting the below error. Definitely I am missing something and I don't know what I am missing.

***************************************************************************

[0530/193129.566:ERROR:main_delegate.cc(684)] Could not load locale pak for en-US
[0530/193129.566:ERROR:main_delegate.cc(691)] Could not load cef.pak
[0530/193129.566:ERROR:main_delegate.cc(708)] Could not load cef_100_percent.pak
[0530/193129.566:ERROR:main_delegate.cc(717)] Could not load cef_200_percent.pak
[0530/193129.566:ERROR:main_delegate.cc(726)] Could not load cef_extensions.pak
[0530/193129.581:ERROR:content_client.cc(269)] No data resource available for id 20418
[0530/193129.581:ERROR:content_client.cc(269)] No data resource available for id 20419
[0530/193129.581:ERROR:content_client.cc(269)] No data resource available for id 20420
[0530/193129.581:ERROR:content_client.cc(269)] No data resource available for id 20421
[0530/193129.581:ERROR:content_client.cc(269)] No data resource available for id 20422
[0530/193129.581:ERROR:content_client.cc(269)] No data resource available for id 20417
[0530/193129.597:ERROR:extension_system.cc(72)] Failed to parse extension manifest.
LOADER: Back to parent (RC: -1073741819)
LOADER: Doing cleanup
LOADER: Freeing archive status for E:\Sriram\learning\python\browser\examples\pyinstaller\dist\cefapp.exe

****************************************************************************

Message has been deleted

Czarek Tomczak

unread,
May 31, 2018, 4:26:26 AM5/31/18
to CEF Python
I undo my previous post. The discovery of binaries is in the hook file, not in spec file. You should make sure that the cefpython3 hook is executed. In the original cefpython3 pyinstaller.spec you can see such code that makes sure the hook was executed:

if not os.environ.get("PYINSTALLER_CEFPYTHON3_HOOK_SUCCEEDED", None):

raise SystemExit("Error: Pyinstaller hook-cefpython3.py script was "

"not executed or it failed")

The errors you get are because binary files are missing, seems like they were not packaged.

srig...@gmail.com

unread,
May 31, 2018, 6:21:27 AM5/31/18
to CEF Python
The "hook-cefpython3.py" is running. I am able to see the INFO of "cef.pak
" & "locales/en-US.pak" during the pyinstaller compilation. I have also added the below in the spec file.

if not os.environ.get("PYINSTALLER_CEFPYTHON3_HOOK_SUCCEEDED", None):

raise SystemExit("Error: Pyinstaller hook-cefpython3.py script was "

"not executed or it failed")

The exe conversion completed successfully without any error. But when I ran the exe, I am facing the same problem.

As per the INFO message, the "cef.pak" & "locales/en-US.pak" are processing in the "datas". I am using the same hook file from the cefpython pyinstaller file. In the hook file, the binary variable is set as NULL.

# Include binaries
binaries = []


Czarek Tomczak

unread,
May 31, 2018, 6:47:38 AM5/31/18
to CEF Python
When you execute the one file binary, it extracts all files to a temporary directory. Check that directory and see what is the structure of files/dirs, what files are missing. See http://pyinstaller.readthedocs.io/en/stable/operating-mode.html#how-the-one-file-program-works

Czarek Tomczak

unread,
May 31, 2018, 7:40:23 AM5/31/18
to CEF Python
You could try change cefpython3 hook, so that it adds binaries files as "binaries" and not as "datas". On Windows it was required to add binaries as datas otherwise errors occured, as pyinstaller was trying to be smart and find dependencies for the DLLs and it was crashing.


On Thursday, May 31, 2018 at 10:21:27 AM UTC, srigking wrote:

srig...@gmail.com

unread,
May 31, 2018, 7:49:32 AM5/31/18
to CEF Python
Both the "cef.pak" & "locales/en-US.pak" are available in the temp/_MEIXXXX folder.

srig...@gmail.com

unread,
May 31, 2018, 7:49:53 AM5/31/18
to CEF Python
Ok Let me try.

Czarek Tomczak

unread,
May 31, 2018, 7:58:21 AM5/31/18
to CEF Python
Check *all* binary files if they exist. Check your ApplicationSettings if you have changed locales_dir_path or resources_dir_path. It might be required set paths to these explicitilly using the _MEI pyinstaller environment variable that is available during execution in freeze mode.

Czarek Tomczak

unread,
May 31, 2018, 8:00:49 AM5/31/18
to CEF Python
The env variable name is "_MEIPASS".

srig...@gmail.com

unread,
May 31, 2018, 10:45:09 AM5/31/18
to CEF Python
I have not changed the locales_dir_path or resources_dir_path. But just to try, I have now changed the locales_dir_path and resources_dir_path to "C:\Python34\Lib\site-packages\cefpython3" & "C:\Python34\Lib\site-packages\cefpython3\locales" folder.

if getattr(sys, 'frozen', False):
tempLocation = sys._MEIPASS
libLocation = {'resources_dir_path': tempLocation, 'locales_dir_path': tempLocation + os.sep + 'locales'}
else:
libLocation = {'resources_dir_path': 'C:\Python34\Lib\site-packages\cefpython3', 'locales_dir_path': 'C:\Python34\Lib\site-packages\cefpython3\locales'}
cef.Initialize(libLocation)

After this change the application not crashed and no error in the console. But the app not loaded fully. It stops in an ideal state and not terminated. The "http://www.google.com" url not displayed in the URL tab and not in the page is not loaded in the browser also.


Console Output:

PyInstaller Bootloader 3.x
LOADER: executable is E:\Sriram\learning\python\browser\examples\pyinstaller\dist\cefapp.exe
LOADER: homepath is E:\Sriram\learning\python\browser\examples\pyinstaller\dist
LOADER: _MEIPASS2 is NULL
LOADER: archivename is E:\Sriram\learning\python\browser\examples\pyinstaller\dist\cefapp.exe
LOADER: Extracting binaries
LOADER: Executing self as child
LOADER: set _MEIPASS2 to C:\Users\sam\AppData\Local\Temp\_MEI22762
LOADER: Setting up to run child
LOADER: Creating child process
LOADER: Waiting for child process to finish...
PyInstaller Bootloader 3.x
LOADER: executable is E:\Sriram\learning\python\browser\examples\pyinstaller\dist\cefapp.exe
LOADER: homepath is E:\Sriram\learning\python\browser\examples\pyinstaller\dist
LOADER: _MEIPASS2 is C:\Users\sam\AppData\Local\Temp\_MEI22762
LOADER: archivename is E:\Sriram\learning\python\browser\examples\pyinstaller\dist\cefapp.exe
LOADER: SetDllDirectory(C:\Users\sam\AppData\Local\Temp\_MEI22762)
LOADER: Already in the child - running user's code.
LOADER: manifestpath: C:\Users\sam\AppData\Local\Temp\_MEI22762\cefapp.exe.manifest
LOADER: Activation context created
LOADER: Activation context activated
LOADER: Python library: C:\Users\sam\AppData\Local\Temp\_MEI22762\python34.dll
LOADER: Loaded functions from Python library.
LOADER: Manipulating environment (sys.path, sys.prefix)
LOADER: Pre-init sys.path is C:\Users\sam\AppData\Local\Temp\_MEI22762\base_library.zip;C:\Users\sam\AppData\Local\Temp\_MEI22762
LOADER: sys.prefix is C:\Users\sam\AppData\Local\Temp\_MEI22762
LOADER: Setting runtime options
LOADER: Bootloader option: pyi-windows-manifest-filename cefapp.exe.manifest
LOADER: Initializing python
LOADER: Overriding Python's sys.path
LOADER: Post-init sys.path is C:\Users\sam\AppData\Local\Temp\_MEI22762\base_library.zip;C:\Users\sam\AppData\Local\Temp\_MEI22762
LOADER: Setting sys.argv
LOADER: setting sys._MEIPASS
LOADER: importing modules from CArchive
LOADER: extracted struct
LOADER: callfunction returned...
LOADER: extracted pyimod01_os_path
LOADER: callfunction returned...
LOADER: extracted pyimod02_archive
LOADER: callfunction returned...
LOADER: extracted pyimod03_importers
LOADER: callfunction returned...
LOADER: Installing PYZ archive with Python modules.
LOADER: PYZ archive: out00-PYZ.pyz
LOADER: Running pyiboot01_bootstrap.py
LOADER: Running pyi_rth_qt4plugins.py
LOADER: Running qt.py
[qt.py] CEF Python 57.0
[qt.py] Python 3.4.4 64bit
[qt.py] PySide 1.2.2 (qt 4.8.5)


I have created seperate onefile exe & bundle exe and compared file by file. All the supported files are in the onefile exe temp folder.

Czarek Tomczak

unread,
May 31, 2018, 10:57:48 AM5/31/18
to CEF Python
Check the debug.log file.

Czarek Tomczak

unread,
May 31, 2018, 11:00:19 AM5/31/18
to CEF Python
Try also setting the "browser_subprocess_path" in ApplicationSettings. Make a full path using the _MEIPASS variable.

srig...@gmail.com

unread,
Jun 1, 2018, 3:16:07 AM6/1/18
to CEF Python
I have set the browser_subprocess_path as _MEIPASS. No luck.

I have enabled the debug and set the "log_severity" to "cef.LOGSEVERITY_VERBOSE".

LOADER: Running qt.py
[qt.py] CEF Python 57.0
[qt.py] Python 3.4.4 64bit
[qt.py] PySide 1.2.2 (qt 4.8.5)
C:\Users\sam\AppData\Local\Temp\_MEI53562
[0601/123245.511:INFO:cefpython_app.cpp(132)] [Browser process] OnBeforeChildProcessLaunch() command line: "C:\Users\sam\AppData\Local\Temp\_MEI53562" --type=gpu-process --no-sandbox --lang=en-US --locales-dir-path="C:\Users\sam\AppData\Local\Temp\_MEI53562\locales" --log-file="C:\Users\sam\AppData\Local\Temp\_MEI53562" --log-severity=verbose --resources-dir-path="C:\Users\sam\AppData\Local\Temp\_MEI53562" /prefetch:2

[0601/123245.511:INFO:cefpython_app.cpp(132)] [Browser process] OnBeforeChildProcessLaunch() command line: "C:\Users\sam\AppData\Local\Temp\_MEI53562" --type=gpu-process --no-sandbox --lang=en-US --locales-dir-path="C:\Users\sam\AppData\Local\Temp\_MEI53562\locales" --log-file="C:\Users\sam\AppData\Local\Temp\_MEI53562" --log-severity=verbose --resources-dir-path="C:\Users\sam\AppData\Local\Temp\_MEI53562" --disable-direct-composition --supports-dual-gpus=false --gpu-driver-bug-workarounds=7,10,18,19,20,23,41,61,74 --disable-gl-extensions="GL_KHR_blend_equation_advanced GL_KHR_blend_equation_advanced_coherent" --gpu-vendor-id=0x8086 --gpu-device-id=0x0102 --gpu-driver-vendor="Intel Corporation" --gpu-driver-version=9.17.10.4459 --gpu-driver-date=5-19-2016 --lang=en-US --locales-dir-path="C:\Users\sam\AppData\Local\Temp\_MEI53562\locales" --log-file="C:\Users\sam\AppData\Local\Temp\_MEI53562" --log-severity=verbose --resources-dir-path="C:\Users\sam\AppData\Local\Temp\_MEI53562" /prefetch:2

[0601/123245.511:VERBOSE1:pref_proxy_config_tracker_impl.cc(151)] 000000000AA76960: set chrome proxy config service to 000000000AA76FA0
[0601/123245.511:VERBOSE1:pref_proxy_config_tracker_impl.cc(278)] 000000000AA76960: Done pushing proxy to UpdateProxyConfig
[0601/123245.526:VERBOSE1:multi_log_ct_verifier.cc(75)] Adding CT log: Google 'Pilot' log
[0601/123245.526:VERBOSE1:multi_log_ct_verifier.cc(75)] Adding CT log: Google 'Aviator' log
[0601/123245.526:VERBOSE1:multi_log_ct_verifier.cc(75)] Adding CT log: DigiCert Log Server
[0601/123245.526:VERBOSE1:multi_log_ct_verifier.cc(75)] Adding CT log: Google 'Rocketeer' log
[0601/123245.526:VERBOSE1:multi_log_ct_verifier.cc(75)] Adding CT log: Symantec log
[0601/123245.526:VERBOSE1:multi_log_ct_verifier.cc(75)] Adding CT log: Venafi log
[0601/123245.526:VERBOSE1:multi_log_ct_verifier.cc(75)] Adding CT log: Symantec 'Vega' log
[0601/123245.526:VERBOSE1:multi_log_ct_verifier.cc(75)] Adding CT log: CNNIC CT log
[0601/123245.526:VERBOSE1:multi_log_ct_verifier.cc(75)] Adding CT log: WoSign log
[0601/123245.526:VERBOSE1:multi_log_ct_verifier.cc(75)] Adding CT log: StartCom CT log
[0601/123245.526:VERBOSE1:multi_log_ct_verifier.cc(75)] Adding CT log: Google 'Skydiver' log
[0601/123245.526:VERBOSE1:multi_log_ct_verifier.cc(75)] Adding CT log: Google 'Icarus' log
[0601/123245.526:VERBOSE1:multi_log_ct_verifier.cc(75)] Adding CT log: Izenpe log
[0601/123245.526:VERBOSE1:multi_log_ct_verifier.cc(75)] Adding CT log: Certly.IO log
[0601/123245.559:INFO:cef_log.cpp(8)] [Browser process] CreateBrowserSync() called

[0601/123245.560:INFO:cef_log.cpp(8)] [Browser process] navigateUrl: https://www.google.com/

[0601/123245.561:INFO:cef_log.cpp(8)] [Browser process] CefBrowser::CreateBrowserSync()

[0601/123245.562:VERBOSE1:webrtc_internals.cc(99)] Could not get the download directory.
[0601/123245.588:INFO:cef_log.cpp(8)] [Browser process] GetPyBrowser(): create new PyBrowser, browserId=1

[0601/123245.591:INFO:cefpython_app.cpp(132)] [Browser process] OnBeforeChildProcessLaunch() command line: "C:\Users\sam\AppData\Local\Temp\_MEI53562" --type=renderer --no-sandbox --disable-databases --primordial-pipe-token=1A2235E7A5B875BE332D25F99689CFB4 --lang=en-US --lang=en-US --locales-dir-path="C:\Users\sam\AppData\Local\Temp\_MEI53562\locales" --log-file="C:\Users\sam\AppData\Local\Temp\_MEI53562" --log-severity=verbose --resources-dir-path="C:\Users\sam\AppData\Local\Temp\_MEI53562" /prefetch:1

[0601/123245.598:INFO:cef_log.cpp(8)] [Browser process] CefBrowser::CreateBrowserSync() succeeded

[0601/123245.599:INFO:cef_log.cpp(8)] [Browser process] CefBrowser window handle = 787712


It went to ideal after this. If enable the "single_process" in the ApplicationSettings, the entire app is working. But as per the official docs, it is less stable. I think there is some problem in creating child process in windows.

srig...@gmail.com

unread,
Jun 1, 2018, 3:46:13 AM6/1/18
to CEF Python
I have not read your comments properly. Now I have given the FULL PATH for the subprocess in ApplicationSettings 'browser_subprocess_path' and it is now working. This is the settings I have applied now.

if getattr(sys, 'frozen', False):

appSettings = {
'resources_dir_path': sys._MEIPASS,
'locales_dir_path': sys._MEIPASS + os.sep + 'locales',
'browser_subprocess_path': sys._MEIPASS + os.sep + 'subprocess.exe',
}
else:
appSettings = {


'resources_dir_path': 'C:\Python34\Lib\site-packages\cefpython3',
'locales_dir_path': 'C:\Python34\Lib\site-packages\cefpython3\locales'
}

cef.Initialize(appSettings)

I have missed the "subprocess.exe" in the "browser_subprocess_path". Thanks for your help Czarek. It is now working.

Reply all
Reply to author
Forward
0 new messages