I am trying to get Pyinstaller 3.5 to create a "onefile" executable but it keeps generating a "onedir" instead.
My files are all in one directory. There is a main program that imports two other modules which in turn import a third. The program functions properly when run directly in Python 3.7.4. The "onedir" version generated by Pyinstaller also works. I'm running 64 bit Windows 10 Pro on a Surface Book 2.
The command I'm using to generate the file is:
pyinstaller --onefile --windowed --additional-hooks-dir=. qualys_admin.spec
My program uses wx, pubsub, xmltodict, requests, and pandas. The additional hook file is for xlrd which pandas needs to read a xlsx file.
My spec file looks like this:
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
# work-around for https://github.com/pyinstaller/pyinstaller/issues/4064
import distutils
if distutils.distutils_path.endswith('__init__.py'):
distutils.distutils_path = os.path.dirname(distutils.distutils_path)
addedfiles = ('qualys_admin.ini', '.')
a = Analysis(['qualys_admin.py'],
pathex=['C:\\Users\\secops-sw\\Documents\\qualys-
administration\\qualysadmin'],
binaries=[],
datas=[addedfiles],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='qualys_admin',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='qualys_admin')
I wrote a tiny "hello world" program to take the complexity of my program off the table. I was able to generate both a "onedir" and a "onefile" successfuly. So I know where to look for the standalone executable.
For my qualys_admin app, that executable is definitely not being generated and I cannot find any warnings to indicate why.
Does anyone have any ideas?
It is not working because your spec file is configured for one directory mode. You need to create the spec file with the one file flag.
pyi-makespec --onefile yourscript.py
Then you can modify your spec sheet and build the app using the custom spec sheet.
Related
Mac Big Sur, python 3.9, pyinstaller 4.3.
I've seen this question posted elsewhere, e.g. PyInstaller OS X app runs from command line, but not Finder window, but can't quite understand the proposed solutions. I have a Mac .app created using tkinter and pyinstaller that functions fine at the terminal when I type
./dist/MyApplication.app/Contents/MacOS/MyApplication
However, when I double click on the .app in the Finder, the program icon appears briefly on my computer's dock before disappearing. No error message at all.
Here is my .spec file:
block_cipher = None
a = Analysis(['MyApplication.py'],
pathex=
['/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages',
'/Users/fishbacp/Desktop'],
binaries=[],
datas=[('/Users/fishbacp/Desktop/background.png','.')],
hiddenimports=['_tkinter','PIL'],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='MyApplication',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='MyApplication')
app =
BUNDLE(coll,name='MyApplication.app',
icon='/Users/fishbacp/Desktop/spectrum.ico',
bundle_identifier=None,
info_plist={'LSEnvironment': {'LANG': 'de_DE.UTF-8',
'LC_CTYPE': 'de_DE.UTF-8'}})
I had same problem (but used one folder mode instead of packaging as an .app), when double click in finder, it will open console and immediately close it.
And my case was due to uncaught exception in my program, which failed to load a file from the folder, and correct the path fixed the problem.
from pathlib import Path
# The file path should be relative to the packaged folder path
file_path = Path(__file__).resolve().with_name("some/path/to/the/file")
It might not be your case but my guess is your program exists due to unexpected condition and that's why it disappears soon, and file path is quite often not handled properly when using PyInstaller.
Hope it can help someone.
I've created a script to automatize creating new executable versions of my app. The thing is that when I run command pyinstaller myapp.spec from commandline on windows platform it creates different file than when I run in from my script (which doesn't work BTW). Below is a snippet of code I use to create .exe.
SNIPPET
SPEC_PATH = 'venv_python37'
file = 'myapp.spec'
os.chdir(SPEC_PATH)
command = r'{} {}'.format('pyinstaller', file)
os.system(command)
When I run that I see all prints of pyinstaller and at the end there is a:
55830 INFO: Building COLLECT COLLECT-00.toc completed successfully.
Which looks exacly like when I run this command directly from commandline.
DIFFERENCES
myapp.exe size created from my script is 27MB but from commandline it is 40MB
When I run the .exe created from myscript there is an error that says:
The 'gcloud' distribution was not found and it is required by the application
That looks like when I run it from myscrip it user another dependencies than from commandline and I think command from myscript doesn't use dependencies from my virtual enviroment. A'm I right?
MYAPP.SPEC
# -*- mode: python -*-
from kivy.deps import sdl2, glew
block_cipher = None
_excludes=("'tcl'", "'tk'", "'FixTk'", "'_tkinter'", "'tkinter'", "'Tkinter'")
a = Analysis(['C:\\Users\\Patryk\\PycharmProjects\\myapp\\myapp.py'],
pathex=['venv_python37', 'C:\\Users\\Patryk\\PycharmProjects\\myapp'],
binaries=None,
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=_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,
*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
name='BajotWorkSpace',
debug=False,
strip=False,
upx=True,
console=True,
runtime_tmpdir=None,
icon='C:\\Users\\Patryk\\PycharmProjects\\myapp\\main_logo.ico' )
coll = COLLECT(exe,
Tree('C:\\Users\\Patryk\\PycharmProjects\\myapp\\Added_files'),
name='myapp')
I've found the reason. When I run .spec from my script it uses packages from my virtual enviroment but the same command run from commandline uses global packages. The issue with gcloud module was lack of hook file in Lib\site-packages\PyInstaller\hooks. Adding file named hook-gcloud.py with below code made my .exe work.
from PyInstaller.utils.hooks import copy_metadata
datas = copy_metadata('gcloud')
I have 2 files, One is Main.py other one is Autoe.ui, I want both as a single .exe
I tried
pyinstaller -w --add-data="Autoe.ui;." Main.py
This works just fine, but it creates lot of other files as well, I wanted just a single exe, So I tried this
pyinstaller.exe -w --onefile --add-data="Autoe.ui;." Main.py
This creates a single .exe but it won't run, I get a pop-up saying "Failed to execute script Main"
I had a similar problem with the Kivy app. In my case it was a kv file, not a ui. Maybe what I did will help you.
In the folder with the * .py file I ran the command:
pyinstaller --onefile -y --clean --windowed --icon=someicon.ico main.py
The main.spec file appeared in the folder. I have edited it.
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(["main.py"],
pathex=["C:\\Users\\underground\\Desktop\\gdc"], #<<<<<<<path to folder of your app
binaries=[]
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
a.datas += [('gdc.kv', 'C:\\Users\\underground\\Desktop\\gdc\\gdc.kv', 'DATA')] #<<<< I added kv file to a.datas
excluded_binaries = ['VCRUNTIME140.dll'] #<<<< I disabled this library because my app won't start on win10
a.binaries = TOC([x for x in a.binaries if x[0] not in excluded_binaries])
exe = EXE(pyz, Tree('C:\\Users\\underground\\Desktop\\gdc\\Data','Data'),
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='main',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=False,
upx_exclude=[],
runtime_tmpdir=None,
console=False , icon='ikona.ico')
When I edited the spec file, I ran pyintaller again but gave the spec file instead of the * .py file.
pyinstaller main.spec
...that's all.
You can also try the GUI version - auto-py-to-exe instead of pyinstaller.
I am trying to convert my code into an exe using pyinstaller spec.
I ran pyinstaller with the following command:
pyinstaller --clean --add-data lib_lightgbm.dll;\compile orca.spec
The exe fails with the error:
main__.PyInstallerImportError: Failed to load dynlib/dll
'C:\\Users\\...\\lightgbm\\../compile\\lib_lightgbm.dll'. Most probably this
dynlib/dll was not found when the application was frozen.
I have tried adding lightgbm.dll through binaries, but didnt work. I also tried manually copying it to the destination after the exe is created. That didnt work either. Most of the questions about pyinstaller and lib_lightgbm.dll failed to answer my issue. Can someone please suggest a solution? I am at my wits end at the moment.
Here is my spec file:
# -*- mode: python -*-
import sys
sys.setrecursionlimit(5000)
block_cipher = None
a = Analysis(['mycode.py'],
pathex=['C:\\mycode\\source code'],
binaries=[],
datas=[],
hiddenimports=['cython', 'sklearn', 'sklearn.feature_extraction','sklearn.pipeline', 'sklearn.ensemble', 'sklearn.neighbors.typedefs', 'sklearn.neighbors.quad_tree', 'sklearn.tree._utils'],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='mycode',
debug=True,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='mycode')
When you build from a spec file, those options cannot be changed.
so either add the tuple to the datas section, or ommit the spec file and use all the parameters for pyinstaller
I'm not 100% sure this is the fix, but there should be something in your datas section of you spec file. So I'd investigate that. you can also build from a spec file using pyinstaller <spec file here> when you're done editing it.
https://pyinstaller.readthedocs.io/en/stable/spec-files.html
I have programmed a python script using tkinter and want to turn it into an exe file. I have tried running it as a .pyw file and it only runs the GUI window without the command line which is what I want. However, when using Pyinstaller to convert my script to a .exe file it opens and runs fine but the command line always opens as well. This has happened when converting both .py and .pyw files and it also occurs when I specify in the command prompt --windowed or --noconsole. I have even tried to edit the spec file of my .exe to see if the console is set to true but I find in the code "console=False". I cannot find any other fixes on previous questions or on the pyinstaller issus page and so I have had to ask myself.
This is the spec file
# -*- mode: python -*-
block_cipher = None
a = Analysis(['D:\\zebsu\\Documents\\simple_calculator_3.py'],
pathex=['C:\\Users\\zebsu'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='simple_calculator_3',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='simple_calculator_3')
I'm fairly new to Pyinstaller myself but the following command has worked for me:
pyinstaller -w YourPythonFile.py.
Hope this helps.