PyInstallerで作成されたexeファイルの実行パス取得するには?
PyInstallerで作成されたexeファイルは、実行時はexeファイルからファイル展開されて実行場所が変わります。
展開先例):%USERPROFILE%/AppData/Local/Temp/_MEIxxxxxx
以下がexeファイルで実行されたイメージ例です。
この際に困ってしまうのは、config.iniなどの設定ファイルが実行ファイル直下にあると想定してexe化した場合に、うまく動作しなくなってしまうことが考えられます。
実際にexeファイルが存在する絶対パスを取得するコードを紹介します。
PyInstallerで作成されたexeファイルの実行パスを取得するサンプルコード
サンプルコードを紹介します。ファイル名はexepath.pyとしています。
# pyinstaller exepath.py --onefile
import os
import sys
def get_exepath(file_name):
"""
PyInstallerで実行しているexeファイルのフルパスを取得する。
.pyファイルを実行する場合には相対パス
.exeファイルの場合にはフルパスを返します。
利用用途
--------------------------------------------
PyInstallerで実行しているexeファイルでconfig.iniを利用したい場合など。
実行結果例
--------------------------------------------
.pyファイルの場合
引数にファイル名(config.iniなど)を指定すると
戻り値 config.ini
.exeファイルの場合
引数にファイル名(config.iniなど)を指定すると
戻り値 C:\Users\work\Documents\test_py\config.ini ※exeファイルの置き場所によりパスは変わります。
Args:
file_name (str): 取得したいファイルの名前。
Returns:
str: exeファイル実行時はファイルの絶対パス。
"""
# PyInstallerでexe化されている場合、sysモジュールの属性 'frozen' が True になり、'_MEIPASS' という属性が存在する。
# この場合、実行ファイルが配置されているディレクトリのパスを取得して、そのパスとファイル名を結合してファイルのフルパスを作成する。
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
# PyInstallerでexe化されている場合のパス
base_path = os.path.dirname(os.path.abspath(sys.executable))
# ファイル名と結合する
file_path = os.path.join(base_path, file_name)
else:
file_path = file_name
# exeの場合は絶対パスに変換して返す
return file_path
# 関数のテスト
if __name__ == "__main__":
# ファイル名を設定する。
ini_file_name = 'config.ini'
# 引数にファイル名を設定して実行
path = get_exepath(ini_file_name)
print(f"INIファイルのパス: {path}")
# 引数ファイル名を設定して実行
path = get_exepath("")
print(f"EXEファイルのパス: {path}")
実行結果
exepath.pyファイルから起動した例
INIファイルのパス: config.ini
EXEファイルのパス:
exepath.pyファイルから、pyinstaller exepath.py --onefile
でexeファイルから起動した例
INIファイルのパス: C:\Users\work\Documents\test_py\config.ini
EXEファイルのパス: C:\Users\work\Documents\test_py\
このようにexeファイルから起動した場合にはexeファイルのフルパスが返ります。
最後に
以上がPyInstallerで作成されたexeファイルの実行パスを取得する方法です。
exeファイルとiniファイルを配布するようなプログラム作成の際に利用してみてはいかがでしょうか。
コメント