3

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")
Ahmed AEK
  • 8,584
  • 2
  • 7
  • 23
invisible boi
  • 106
  • 1
  • 8

2 Answers2

4

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().

Ahmed AEK
  • 8,584
  • 2
  • 7
  • 23
  • 1
    This does not work for one-file executables as one comment in the linked thread pointed out. The variable `sys._MEIPASS` holds the path to the temp directory. It recommends to use `sys.executable` for one-file executables which in my test worked: `os.path.dirname(sys.executable)` – cweigel May 09 '23 at 07:01
  • 1
    @cweigel you are correct, i wonder why no-one found that out in 2 years, it even had 3 upvotes, anyway, the answer is updated and it's now correct and explains the problem in detail. – Ahmed AEK May 09 '23 at 17:32
  • This one might help further with examples: https://stackoverflow.com/a/72060275/10789707 – Lod Jul 29 '23 at 21:28
0

Use terminal

pyinstaller --specpath DIR main.py

file main.exe in dist\main\main.exe Run file main.exe then files save in the executable directory in your projcet