Python create folder next to .exe - python

I am using Vizard to create an .exe file off a python script. I need this script to create a folder which resides next to the .exe file
if getattr(sys, 'frozen', False):
logging.warning('Application is exe')
loggingPath = os.path.dirname(sys.executable)
logging.warning(os.getcwd())
elif __file__:
loggingPath = os.path.dirname(__file__)
logging.warning('Application is script')
logging.warning(os.getcwd())
if not os.path.exists(loggingFolder):
logging.warning('Directory not existing... creating..')
os.makedirs(loggingFolder)
works fine when I execute from the IDE, but in an exe file it throws data in the Appdata Folder in Windows/Users/Temp/randomfoldername.
Also, I always Application is script, even when its packed into exe.
Can someone point me in the right direction here?
Thanks in advance

The sys module does not have any attribute frozen, which results in the first if statement always returning False.
sys.executable will give the path to the python interpreter binary, ie. for Windows the path of your python.exe file, which I cannot see why you would need for this.
If what you want is to ensure that the file running is a .exe file, then make a folder next to it, it may be simpler to just check if the filename ends with .exe?
if __file__.endswith('.exe'):
loggingFolder = os.path.join(os.path.dirname(__file__), 'foldername')
if not os.path.exists(loggingFolder):
os.makedirs(loggingFolder)

if you just want to create a folder at runtime, then another (possibly easier) method is to run your vizard program from within a batch file and create the folder first in the batch file
e.g. create run_viz_prog.bat with content like this :-
mkdir new_folder
my_viz_prog.exe

Related

After compiling a python script to EXE the Archive method doesn't work

I have a python script that I compiled to an EXE, one of the purposes of it is to extract a 7z file and save it to a destination.
If I'm running it from PyCharm everything works great, this is the code:
def delete_old_version_rename_new(self):
winutils.delete(self.old_version)
print("Extracting...")
Archive(f"{self.new_version}_0.7z").extractall(f"{self.destination}")
print("Finished")
os.rename(self.new_version, self.new_name)
I used pyinstaller to compile the program and used to command pyinstaller --onefile --paths {path to site packages} main.py
Thanks!
Single-file executables self-extract to a temporary folder and run from there, so any relative paths will be relative to that folder not the location of executable you originally ran.
My solution is a code snippet such as this:
if getattr(sys, 'frozen', False):
app_path = os.path.dirname(sys.executable)
else:
app_path = os.path.dirname(os.path.abspath(__file__))
which gives you the location of the executable in the single-file executable case or the location of the script in the case of running from source.
See the PyInstaller documentation here.
Eventually i just used a 7z command line i took from https://superuser.com/questions/95902/7-zip-and-unzipping-from-command-line
and used os.system() to initialize it.
Since my program is command line based it worked even better since its providing a status on the extraction process.
Only downside is i have to move the 7z.exe to the directory of my program.

os.path.isfile(os.path.abspath("adb.exe")) Return false

Why does os.path.isfile(os.path.abspath("adb.exe")) return false?
i have adb.exe in script dir same with os.path.isfile(os.path.abspath("fastboot.exe"))
but when i copy them to my python dir, and then start interactive shell, eg. os.path.isfile(os.path.abspath("adb.exe")) gives me True.
Or there is better way to validate if file exist in script dir.
The reason os.path.isfile(os.path.abspath("adb.exe")) returns False is because when you run the script, python is actually running from its installation directory, not the script location.
If you want to get the current folder path you can use:
os.path.dirname(os.path.abspath(__file__))
or as #blakev suggested:
os.path.split(__file__)[0]
Thus you can check a file exists in the scripts location using:
os.path.isfile(os.path.dirname(os.path.abspath(__file__)) + os.sep + filename)
Note:
os.sep contains the appropriate separator used by your operating systems file system, so \ on Windows systems.
__file__ exists only when running a script file, it won't work just running python in the command line. It returns the full path and name of the script. As an example, running a script on my desktop called script.py it may return C:\Users\Nick A\Desktop\script.py

Python thinks file is still a .py when it is .exe

Got some weird behavior here. Basically I am using import os to find the path of the exe file and then I use that path in a batch file to move the exe file. I've also used pyinstaller to make the program an exe.
Now here is where the issue occurs. The os commands works well, but it thinks the file is still a .py
This is really odd because I made this variable:
dirName = os.path.abspath(__file__)
Now, this finds the correct directory and the correct file name(but not file type)
Then I use that variable to write down which directory the file is currently in like this:
move.write('move /Y "' + str(dirName) + '" (code continues here, but not important)
This works when the file is a .py but not when it is a .exe
I hope this makes sense, feel free to ask and/or edit if anything is unclear.
Current output: The system cannot find the file specified.
Wanted output: 1 file(s) moved.
You can specify the extension you want by this way:
files = os.listdir('/your/directory')
for filename in files:
if filename.endswith(".exe"):#or extension you want
#copy file you want

PyInstaller cannot add .txt files

I'm fairly new with programming (and with Python) and the Stack Overflow question/response system allowed me to resolve all my problems until now. I didn't find any post directly addressing my current issue, but have to admit that I don't really know what's wrong. Let me explain.
I'm trying to make an executable file of a *.py script using PyInstaller. There's no problem doing it with a simple Python script (using --onefile), but it does not work when it comes to a more complex program that uses other *.py and *.txt files. I know that I need to modify the specification file and tried many alternatives - adding hidden files for instance.
Here are the files:
UpdatingStrategy.py (the target file to transform in executable)
LPRfunctions.py (UpdatingStrategy.py imports functions from this file)
The following *.txt files are read by UpdatingStrategy.py:
Strategy_Observ.txt
Strategy_Problems.txt
Updating_Observ1.txt
Updating_Observ2.txt
Updating_Problems.txt
I'm using Python 3.5 and Windows 10. Tell me if you need extra information.
How do I use the specification file properly and modify it in order to make an executable file of UpdatingStrategy.py?
I have read the PyInstaller documentation, but I lack many key principles and I couldn't make it work.
After the line
a = Analysis( ... )
add
a.datas += [
("/absolute/path/to/some.txt","txt_files/some.txt","DATA"),
("/absolute/path/to/some2.txt","txt_files/some2.txt","DATA"),
("/absolute/path/to/some3.txt","txt_files/some3.txt","DATA"),
]
Then in your program use the following to get the resource path of your .txt files.
def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = sys._MEIPASS
except Exception:
base_path = os.environ.get("_MEIPASS2",os.path.abspath("."))
return os.path.join(base_path, relative_path)
...
txt_data = open(resource_path("txt_files/some.txt")).read()
Make sure you build it like python -m PyInstaller my_target.spec ... do not call PyInstaller directly against your .py file after you have edited your specification file or it will overwrite your edited file...
Anyone reading this in 2021... I've just run into similar issue with Pyinstaller. Needed to add a text file to my python code:
pyinstaller --add-data "/my/path/to/mytextfile.txt:/path/mytextfile.txt" mypython.py --onedir or --onefile
No matter if onedir or onefile, my code just never found the text file. Infact it threw the error:
IsADirectoryError: [Errno 21] Is a directory: /path/mytextfile.txt
Which didn't make sense to me because that's a file not a folder. Only when I checked this with the --onedir flag and I followed the path, I realized that pyinstaller would not only create a folder path, but also folder mytextfile.txt and put mytextfile.txt in there... so really the --add-data flag only wants a destination folder not the path to the file.
pyinstaller --add-data "/my/path/to/mytextfile.txt:path" mypython.py
or in the spec file i.e mypython.spec
datas=[('/my/path/to/mytextfile.txt', 'path')]
Should fix this. Note also the "DATA" configuration in the spec file is gone.

"No such file or directory" when files are in the same directory

Both files, the .py file and a .txt file it calls with
champions_list = open('champions.txt','rU').read().split('\n')
are in the file folder C:\Users\[My Name]\Programming\[file name].
I'm calling the .py file through Command prompt and it returns the error
IOError: [Errno 2] No such file or directory: champions.txt
Has this happened to anyone else before?
When you open a file with open('champions.txt'), then the OS expects to find the champions.txt file in the current directory. The current directory is the directory of the command prompt window where you started the program. This is not (necessarily) the same as the directory where the Python script is stored.
You may be able to fix this by doing:
import os
import sys
open(os.path.join(os.path.dirname(sys.argv[0]), 'champions.txt')
This takes the full name of the script in sys.argv[0], takes the directory part, and then joins that to the file name you want. This will open the file in the script directory, not the current directory.
(Note that using sys.argv[0] in this way is OS-dependent, and works on Windows but may not work the same way on other systems.)
Just because the file is in the same folder as the script does not mean the python interpreter knows that the file is there. It is looking for a file in the cwd. You can:
Try using the full absolute path of the file; or
Add the directory containing the file using os.path.append

Categories

Resources