I’m New to Python Coding and just finished my first python scripted
I’m trying to publish my programme so that I can install in on another device.
But as soon as I convert it from .py to .exe with pyinstaller and try to run my programme it gives me the error:
fatal error: failed to execute scrip
Code I used in to convert:
pyinstaller -w file_name.py
pyinstaller -F file_name.py
pyinstaller -i "c:\\icon_file path" file_name.py
am I just missing as step or is there something else I can try to resolve this problem?
I usually code on Visual studio and when I test run everything worked fine.
My .spec file:
block_cipher = None
a = Analysis(['file_name.py'],
pathex=['C:\\Users\\MainUser\\Desktop\\Publishing'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
a.binaries = a.binaries +
[('libsha1.dll','/home/iot/lib/libsha1.dll','BINARY')]
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='file_name',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
runtime_tmpdir=None,
console=True )
```
Usually, this is due to a lack of file when packaging.
When you use PyInstaller, you can use it like this:
python -m PyInstaller .\yourFile.py
then, a yourFile.spec file is generated under this folder.
you should edit this file, add all project file into datas,
a = Analysis(['yourFile.py'],
pathex=['D:\\projectPath\\project'],
binaries=[],
datas=[('D:\\projectPath\\project\\*.py', '.'),
('D:\\projectPath\\project\\UI\\*.ui', 'UI'),
('D:\\projectPath\\project\\other\\*.py', 'other'),
],
...
)
It's simulated up here, a project that contains the UI and other folders. It like a tuple, ('full path', 'folder name').
If you have *.dll on Windows or *.so on Linux, you must be write into binaries:
a.binaries = a.binaries + [('libsha1.so','/home/iot/lib/libsha1.so','BINARY')]
I am guessing you only have one script, so if you use:
Pyinstaller --onefile yourScript.py
Replacing yourScript.py with the name of your python file in the CMD/Terminal, you shouldn't have any problems.
If you are missing a binary, this should help. For example pyinstaller was missing the currency converter module, so I found and it, got the zip file and then ran this in CMD:
Pyinstaller --add-binary "C:\Users\myName\Downloads\eurofxref-hist.zip";currency_converter --onefile myScript.py
Where myScript.py is my Python script, and the link is to the folder with the binary zip file.
Related
I'm trying to make an executable with PyInstaller's onefile option. I've tried many, many different ways of fixing it and I'm absolutely stuck. Specifically, I tried
Pyinstaller and --onefile: How to include an image in the exe file. I made my spec file look like theirs and included the resource_path() function. However, I get the following error:
File "PIL/Image.py", line 2953, in open
FileNotFoundError: [Errno 2] No such file or directory'/var/folders/t5/vkb5xkjs3517p5jlfkbj89vm0000gp/T/_MEIdOLb1O/logo.png'
So I'm not sure if my problem lies in the MEIPASS part, or maybe something with PIL. Another weird part of this is that before this error, my code includes:
self.iconbitmap(r"[workspace]/src/icon.ico")
Which produces no problem, even though both files (icon.ico, logo.png) are located in the same folder as the program that I turn into an executable. If it makes a difference, I'm running this on Mac.
The command I'm currently using:
pyinstaller --noconfirm --onefile --console "[workspace]/src/gui.py" gui.spec
and my spec file:
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['gui.py'],
pathex=['/Users/Freddie/Impruvon/guiwebscraperproject/venv/src'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
for d in a.datas:
if 'pyconfig' in d[0]:
a.datas.remove(d)
break
a.datas += [('logo.png','/Users/Freddie/Impruvon/guiwebscraperproject/venv/src/logo.png', 'Data')]
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='gui',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
Okay well I was sure I had already tried this, but by adding the resource path method from Pyinstaller and --onefile: How to include an image in the exe file, but without changing the spec file, this command works:
pyinstaller --noconfirm --onefile --console --add-data "[workspace]/src/logo.png:." "[workspace]/src/gui.py"
Use this instead and then with pyinstaller convert main file to exe -
If this is the pixmap then add the function below and call it in pixmap
self.label.setPixmap(
QtGui.QPixmap(
self.resource_path("MyPNG_FILE.png")
)
)
Add this function to your code it will work for labels, images etc
### Use this function To attach files to the exe file (eg - png, txt, jpg etc) using pyinstaller
def resource_path(self, relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
base_path = sys._MEIPASS
else:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
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 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.
My issue is related to a pyqt5 executable I created with pyinstaller. The only command I'm using is:
pyinstaller script.py
I'm not very experienced with Pyinstaller's output messages. So I'm posting this question in case someone else can help me figure out what the missing modules or files are.
Here is copy of the entire Compile output:
Github - Pyinstaller Output
Here is a copy of the error that appears.. it happens like in a millisecond:
Any comments or help are appreciated. If you think you have a possible solution, please attempt an answer. I'm sure its worth looking into. Hopefully, its something simple and due to my lack of knowledge.
One other note, I'm importing/using the module ibm_db and the wrapper module ibm_db_dbi.
Here is a copy of my spec file:
# -*- mode: python -*-
block_cipher = None
added_files = [
(r'C:\Python37\Lib\site-packages\ibm_db_dlls\ibm_db.dll', '.')
]
a = Analysis(['InheritMainWindow.py'],
pathex=['c:\\Python37\\PDFMaker_v3\\Prototype',
'C:\\Python37\\Lib\\site-packages\\',
'C:\\Python37\\Lib\\site-packages\\sqlalchemy\\connectors\\',
'C:\\Python37\\Lib\\site-packages\\clidriver\\',
'C:\\Python37\\Lib\\site-packages\\ibm_db_dlls',
'C:\\Python37\\Lib\\site-packages\\ibm_db.py'],
binaries=[('ibm_db.dll', 'ibm_db_dlls')],
datas=[],
hiddenimports=['ibm_db', 'ibm_db_dbi'],
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='InheritMainWindow',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True )
a.binaries = [x for x in a.binaries if os.path.dirname(x[1]).find("IBM") < 0]
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='InheritMainWindow')
PS you should be able to repeat the issue with the following:
import ibm_db
print('hello!')
in command prompt:
pyinstaller hello.py
Upon executing the exe inside the dist folder, you'll get the same above error.
Here is a list of the things I'm tried to resolve this:
1) Providing a full path in the binary like this:
binaries=[(r'C:\Python37\Lib\site-packages\ibm_db_dlls\ibm_db.dll', 'ibm_db_dlls')]
This makes no difference the crash still occurs. And I was already seeing the ibm_db_dlls folder appear in my dist folder. So the binary is being added, but its just not being seen.
2) From the ibm developer forum here:
https://developer.ibm.com/answers/questions/448999/python-3-db2-windows-10-problems-and-script-compil/
A suggested solution was using the --clean option. I've tried this option on 'hello.py', where it only is importing the ibm_db package and it actually works as an exe. But this solution doesn't work on my main project.
Correction: This does NOT work even on the simple hello.py example.
Final update: I've provided a solution below!
So I solved the issue. And I'm expecting this should help a lot of folks. First part of solution is the PATHEX list. I had to update this list to point to all my system's IBM directories:
# -*- mode: python -*-
block_cipher = None
a = Analysis(['InheritMainWindow.py'],
pathex=['c:\\Python37\\PDFMaker_v3',
'C:\\Python37\\Lib\\site-packages\\ibm_db_dlls',
'C:\\Program Files (x86)\\ibm\\gsk8\\lib',
'C:\\Program Files (x86)\\ibm\\gsk8\\bin',
'C:\\Program Files (x86)\\IBM Informix Client SDK\\bin',
'C:\\Program Files (x86)\\IBM\\SQLLIB_01\\BIN',
'C:\\Program Files (x86)\\IBM\\SQLLIB_01\\FUNCTION',
'C:\\Program Files (x86)\\IBM\\SQLLIB_01\\BIN',
'C:\\Program Files (x86)\\IBM\\SQLLIB_01\\FUNCTION',
'C:\\Program Files (x86)\\ibm\\gsk8\\lib',
'C:\\Program Files (x86)\\ibm\\gsk8\\bin',
'C:\\Program Files (x86)\\IBM Informix Client SDK\\bin'],
binaries=[(r'C:\Python37\Lib\site-packages\ibm_db_dlls\ibm_db.dll', 'ibm_db_dlls')],
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='InheritMainWindow',
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,
name='InheritMainWindow')
The next part of the answer was really tricky in figuring out. Its found inside the imb_db.py file:
import os
if 'clidriver' not in os.environ['PATH']:
os.environ['PATH'] = os.environ['PATH'] + ";" + os.path.join(os.path.abspath(os.path.dirname(__file__)), 'clidriver', 'bin')
def __bootstrap__():
global __bootstrap__, __loader__, __file__
import sys, pkg_resources, imp
__file__ = pkg_resources.resource_filename(__name__,'ibm_db_dlls\\ibm_db.dll')
__loader__ = None; del __bootstrap__, __loader__
imp.load_dynamic(__name__,__file__)
__bootstrap__()
I had to update my path variable to include clidriver directory:
C:\Python37\Lib\site-packages\clidriver\bin
the imb_db.py is suppose to be adding this to the path, but its adding in in the wrong format or directory. So that the next line:
__file__ = pkg_resources.resource_filename(__name__,'ibm_db_dlls\\ibm_db.dll')
Ends up not finding the .dll file. So after making these two updates, the program runs and succesfully connects to a remote DB2 database.
#RockAndRoleCoder Thanks for your question and answer. I had met the same situation in Windows7 Python3.7 ibm-db 3.0.1
with your hint,I think the reason is that exe can't find *.dll in clidriver\bin and ibm_db.dll,
and solve it with a similar method in two steps
Frist:
the same as you, add clidriver directory to system path
**\site-packages\clidriver\bin
Second
pack with argument --add-binary
Pyinstaller --add-binary **\Lib\site-packages\ibm_db_dlls\ibm_db.dll;.\ibm_db_dlls myproject.py
Then it's OK!