我使用pyinstaller将程序捆绑到一个.exe文件中,您知道该文件在执行时会创建一个临时的_MEIPASS文件夹。
程序本身具有通过sys.exit()退出的输入方法,该方法将删除_MEIPASS文件夹,但是如果用户通过窗口关闭按钮(X)关闭终端,则该文件夹将保留,并且在下次执行时将保留另一个_MEIPASS文件夹将被创建,一段时间后将导致很多MEIPASS文件夹。
我想知道:
是否有任何方法可以强制.exe文件每次运行时都以相同的名称创建一个特定的文件夹,以避免多个文件夹?
或者只需单击“ X”按钮以使其类似于sys.exit()并删除_MEIPASS文件夹。
我的.spec文件:
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='CookieVPN',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir='E:/CookieVPNtmp/',
console=True , icon='cookievpn.ico')
我也尝试过:
答案 0 :(得分:3)
我找到了某种解决方案,我不确定它是否可以进行故障转移,但是可以解决我的情况。
将此功能添加到您的代码中,并将其作为程序的第一行,以在%tmp%(或程序的_MEI文件夹将位于的任何位置)中找到任何_MEI文件夹并将其删除。 (它不包括当前运行的MEI)
#Imports
import glob
import sys
import os
from shutil import rmtree
def CLEANMEIFOLDERS():
#Getting the current run _MEI path
try:
base_path = sys._MEIPASS
#I don't know if this part is crucial or not since it only works if you don't use
#--onefile in pyinstaller, which makes the use of this function unnecessary
except Exception:
base_path = os.path.abspath(".")
#Extracting the updir of current run path to search for _MEI folders for the previous runs,
#cave man style. Please update this part if you know a better way.
base_path = base_path.split("\\")
base_path.pop(-1)
temp_path = ""
for item in base_path:
temp_path = temp_path + item + "\\"
#Search the path for _MEI folders and delete them if they are not for the current run
mei_folders = [f for f in glob.glob(temp_path + "**/", recursive=False)]
for item in mei_folders:
if item.find('_MEI') != -1 and item != sys._MEIPASS + "\\":
rmtree(item)
该代码有效,但是我希望通过任何改进使代码更轻:)
答案 1 :(得分:1)
首先,当您手动关闭窗口时,脚本将意外关闭(与按ctrl+c
时不同),因此您将无法执行任何操作,因为操作系统会强制关闭它
但是您可以使用--runtime-tmpdir
为文件创建一个固定文件夹,因此不会每次都生成该文件夹:
pyinstaller -F --runtime-tmpdir "Some/Path" test.py
答案 2 :(得分:1)
Sadra的解决方案很好,但是我想保留一些“新”文件夹,以防万一用户使用多个实例运行该工具。因此,除去当前运行之外的所有内容都无济于事。
因此,我想到了检查文件夹的创建日期并删除所有X秒之前的内容的想法。这是代码,以防万一有人需要它:
from shutil import rmtree
import time, os
def deleteOldPyinstallerFolders(time_threshold = 3600): # Default setting: Remove after 1 hour, time_threshold in seconds
try:
base_path = sys._MEIPASS
except Exception:
return # Not being ran as OneFile Folder -> Return
temp_path = os.path.abspath(os.path.join(base_path, '..')) # Go to parent folder of MEIPASS
# Search all MEIPASS folders...
mei_folders = glob.glob(os.path.join(temp_path, '_MEI*'))
for item in mei_folders:
if (time.time()-os.path.getctime(item)) > time_threshold:
rmtree(item)