Search code examples
pythonpathpyinstaller

Pyinstaller executable saves files to temp folder


I am having a problem where I can't save files in the executable directory. Specifically

it saves it to C:\Users\hp\AppData\Local\Temp\_MEI102682\screenie.png

Pyinstaller command: pyinstaller --onefile main.py

code:

import pyautogui
import os

__dir__ = os.path.dirname(os.path.abspath(__file__)) + '\\'

print("Taking screenshot...")

pyautogui.screenshot().save(__dir__ + "screenie.png")
print(f"Saved to: {__dir__}screenie.png\nPress enter to open the file.")
input()
os.system(__dir__ + "screenie.png")

Solution

  • This thread shows the correct way to get the executable path.

    there are a few paths you should know.

    1. sys.executable gets you the location of python.exe during development, but it gets you the path of your .exe after you make one.
    2. sys._MEIPASS which contains the path to the temporary directory used by pyinstaller where your .pyd and .dll are extracted, it also houses any data you put using --add-data. (which is what you are getting)، as it's where pyinstaller expects your libraries to be.

    as pyinstaller sets sys.frozen=True, you can use that to know what to used at runtime.

    import sys, os
    
    def get_script_folder():
        # path of main .py or .exe when converted with pyinstaller
        if getattr(sys, 'frozen', False):
            script_path = os.path.dirname(sys.executable)
        else:
            script_path = os.path.dirname(
                os.path.abspath(sys.modules['__main__'].__file__)
            )
        return script_path
    
    def get_data_folder():
        # path of your data in same folder of main .py or added using --add-data
        if getattr(sys, 'frozen', False):
            data_folder_path = sys._MEIPASS
        else:
            data_folder_path = os.path.dirname(
                os.path.abspath(sys.modules['__main__'].__file__)
            )
        return data_folder_path
    

    if you want the folder of your main script your just call get_script_folder(), but if you want the folder to your "data" (such as embedded images, etc) you should use get_data_folder().