Determining application path in a Python EXE generated by pyInstaller
Solution 1:
I found a solution. You need to check if the application is running as a script or as a frozen exe:
import os
import sys
config_name = 'myapp.cfg'
# determine if application is a script file or frozen exe
if getattr(sys, 'frozen', False):
application_path = os.path.dirname(sys.executable)
elif __file__:
application_path = os.path.dirname(__file__)
config_path = os.path.join(application_path, config_name)
Solution 2:
According to the documentation of PyInstaller, the suggested method of recovering application path is as follows:
#!/usr/bin/python3
import sys, os
if getattr(sys, 'frozen', False):
# If the application is run as a bundle, the PyInstaller bootloader
# extends the sys module by a flag frozen=True and sets the app
# path into variable _MEIPASS'.
application_path = sys._MEIPASS
else:
application_path = os.path.dirname(os.path.abspath(__file__))
Tested for PyInstaller v3.2, but this certainly has been working for earlier versions as well.
Soviut's solution does not work, at least not in general for recent versions of pyInstaller (note that the OP is many years old). For instance, on MacOS, when bundling an application into a one-file-bundle, sys.executable
points only to the location of the embedded archive, which is not the location where the application actually runs after the pyInstaller bootloader has created a temporary application environment. Only sys._MEIPASS
correctly points to that location. Refer to this doc-page for further information on how PyInstaller works.
Solution 3:
I shortened the code a bit.
import os, sys
if getattr(sys, 'frozen', False):
application_path = os.path.dirname(sys.executable)
os.chdir(application_path)
logging.debug('CWD: ' + os.getcwd())
But, sys._MEIPASS
pointed to a wrong directory. I think it also needs sys._MEIPASS
+ \app_name