Определение пути приложения в Python EXE, сгенерированном pyInstaller
У меня есть приложение, которое находится в одном файле .py. Я смог получить pyInstaller, чтобы успешно объединить его в EXE для Windows. Проблема заключается в том, что для приложения требуется файл .cfg, который всегда находится непосредственно рядом с приложением в том же каталоге.
Обычно я строю путь, используя следующий код:
import os
config_name = 'myapp.cfg'
config_path = os.path.join(sys.path[0], config_name)
Однако, похоже, sys.path пуст, когда он вызван из EXE, сгенерированного pyInstaller. Такое же поведение возникает, когда вы запускаете интерактивную командную строку python и пытаетесь извлечь sys.path [0].
Есть ли более конкретный способ получить путь к текущему запущенному приложению, чтобы я мог найти файлы, относящиеся к нему?
Ответы
Ответ 1
Я нашел решение. Вам нужно проверить, работает ли приложение как script или как замороженное 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)
Ответ 2
В соответствии с документацией pyInstaller предложенный способ восстановления пути приложения выглядит следующим образом:
#!/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__))
Протестировано для pyInstaller v3.2, но это, безусловно, работает и для более ранних версий.
Решение Soviut не работает, по крайней мере, не для последних версий pyInstaller (обратите внимание, что OP много лет). Например, в MacOS при наборе приложения в пакет с одним файлом sys.executable
указывает только на местоположение внедренного архива, который не является местом, где приложение действительно работает после того, как загрузчик загрузчика pyInstaller создал временное приложение Окружающая среда. Только sys._MEIPASS
правильно указывает на это местоположение. Для получения дополнительной информации о том, как работает pyInstaller, обратитесь к этой странице doc.
Ответ 3
os.path.dirname(sys.argv[0])
Это работает для меня.
Ответ 4
Я немного сократил код.
import os, sys
if getattr(sys, 'frozen', False):
application_path = os.path.dirname(sys.executable)
os.chdir(application_path)
logging.debug('CWD: ' + os.getcwd())
Но sys._MEIPASS
указал на неправильный каталог. Я думаю, что также требуется sys._MEIPASS
+ \app_name