问题描述
C:\Users\Admin\AppData\Local\Temp文件夹爆满,主要占用大的文件夹名称都含有“_MEI”字符。
原因
使用Python的Pyinstaller库打包exe程序,会导致C盘Temp中的含“_MEI”名称文件夹不断累加。
官方说明
原文:
What PyInstaller Does and How It Does It — PyInstaller 3.3.1 documentation
How the One-File Program Works
The bootloader is the heart of the one-file bundle also. When started it creates a temporary folder in the appropriate temp-folder location for this OS. The folder is named , where xxxxxx is a random number.
_MEIxxxxxx
The one executable file contains an embedded archive of all the Python modules used by your script, as well as compressed copies of any non-Python support files (e.g. files). The bootloader uncompresses the support files and writes copies into the the temporary folder. This can take a little time. That is why a one-file app is a little slower to start than a one-folder app.
.so
After creating the temporary folder, the bootloader proceeds exactly as for the one-folder bundle, in the context of the temporary folder. When the bundled code terminates, the bootloader deletes the temporary folder.
(In Linux and related systems, it is possible to mount the folder with a “no-execution” option. That option is not compatible with a PyInstaller one-file bundle. It needs to execute code out of .)
/tmp/tmp
Because the program makes a temporary folder with a unique name, you can run multiple copies of the app; they won’t interfere with each other. However, running multiple copies is expensive in disk space because nothing is shared.
The folder is not removed if the program crashes or is killed (kill -9 on Unix, killed by the Task Manager on Windows, “Force Quit” on Mac OS). Thus if your app crashes frequently, your users will lose disk space to multiple temporary folders.
_MEIxxxxxx_MEIxxxxxx
It is possible to control the location of the folder by using the command line option. The specified path is stored in the executable, and the bootloader will create the folder inside of the specified folder. Please see Defining the Extraction Location for details.
_MEIxxxxxx
--runtime-tmpdir_MEIxxxxxx
Note
Do not give administrator privileges to a one-file executable (setuid root in Unix/Linux, or the “Run this program as an administrator” property in Windows 7). There is an unlikely but not impossible way in which a malicious attacker could corrupt one of the shared libraries in the temp folder while the bootloader is preparing it. Distribute a privileged program in one-folder mode instead.
Note
Applications that use os.setuid() may encounter permissions errors. The temporary folder where the bundled app runs may not being readable after setuid is called. If your script needs to call setuid, it may be better to use one-folder mode so as to have more control over the permissions on its files.
翻译
单文件程序的工作原理
引导加载程序也是单文件捆绑包的核心。 启动后,它会创建一个临时文件夹 在此操作系统的相应临时文件夹位置。 文件夹名为 ,其中 xxxxxx 是随机数。
_MEIxxxxxx
一个可执行文件包含所有 Python 的嵌入式存档 脚本使用的模块,以及 任何非 Python 支持文件的压缩副本(例如 文件)。 引导加载程序解压缩支持文件并写入副本 进入临时文件夹。 这可能需要一点时间。 这就是为什么单文件应用程序启动速度稍慢的原因 而不是一个文件夹的应用程序。
.so
创建临时文件夹后,引导加载程序 与单文件夹捆绑包完全相同, 在临时文件夹的上下文中。 当捆绑代码终止时, 引导加载程序将删除临时文件夹。
(在 Linux 和相关系统中,这是可能的 使用“no-execution”选项挂载文件夹。 该选项与 PyInstaller 单文件捆绑包不兼容。它需要执行 的代码。
/tmp/tmp
由于该程序会创建一个具有唯一名称的临时文件夹, 您可以运行该应用程序的多个副本; 它们不会相互干扰。 但是,运行多个副本在磁盘空间中成本很高,因为 不共享任何内容。
如果程序崩溃,则不会删除该文件夹 或被杀死(在 Unix 上杀死 -9,在 Windows 上被任务管理器杀死, Mac OS 上的“强制退出”)。 因此,如果您的应用程序经常崩溃,您的用户将失去磁盘空间 多个临时文件夹。
_MEIxxxxxx_MEIxxxxxx
可以通过以下方式控制文件夹的位置 使用命令行选项。指定的路径为 存储在可执行文件中,引导加载程序将在指定文件夹内创建文件夹。有关详细信息,请参阅定义提取位置。
_MEIxxxxxx--runtime-tmpdir_MEIxxxxxx
注意
不要向单文件可执行文件授予管理员权限 (Unix/Linux 中的 setuid 根目录,或“以管理员身份运行此程序” 属性)。 恶意攻击者有一种不太可能但并非不可能的方式 损坏临时文件夹中的一个共享库 当引导加载程序正在准备它时。 改为以单文件夹模式分发特权程序。
注意
使用 os.setuid() 的应用程序可能会遇到权限错误。 运行捆绑应用的临时文件夹可能无法读取 调用 setuid 后。如果您的脚本需要 调用 Setuid,最好使用单文件夹模式 以便更好地控制其文件的权限。
解决
1.使用PyInstaller的--clean
选项
原文:Using PyInstaller — PyInstaller 3.3.1 documentation
-h, --help | 显示此帮助消息并退出 show this help message and exit |
-v, --version | 显示程序版本信息并退出。 Show program version info and exit. |
--distpath DIR | 捆绑应用的放置位置(默认值:./dist) Where to put the bundled app (default: ./dist) |
--workpath WORKPATH | |
将所有临时工作文件(.log、.pyz)放在哪里 等等(默认值:./build) Where to put all the temporary work files, .log, .pyz and etc. (default: ./build) | |
-y, --noconfirm | |
替换输出目录(默认值: SPECPATH/dist/SPECNAME) 而不要求 确认 Replace output directory (default: SPECPATH/dist/SPECNAME) without asking for confirmation | |
--upx-dir UPX_DIR | |
UPX 实用程序的路径(默认:搜索执行 路径) Path to UPX utility (default: search the execution path) | |
-a, --ascii | 不包括 unicode 编码支持(默认值: 如果有的话,包括在内) Do not include unicode encoding support (default: included if available) |
--clean | 清理 PyInstaller 缓存并删除临时文件 在建造之前。 Clean PyInstaller cache and remove temporary files before building. |
--log-level LEVEL | |
生成时控制台消息中的详细信息量。水平 可以是 TRACE、DEBUG、INFO、WARN、ERROR、 CRITICAL(默认值:INFO)。 Amount of detail in build-time console messages. LEVEL may be one of TRACE, DEBUG, INFO, WARN, ERROR, CRITICAL (default: INFO). |
在打包时使用--clean
标志,这会告诉PyInstaller在每次构建前清除之前的临时文件。命令示例:
pyinstaller --clean your_script.py
注意,这个选项仅影响构建过程中的临时文件,不会直接影响运行时的 _MEI
文件夹。
2.在Python中自动清理
在应用退出时添加清理临时文件的代码。可以通过以下Python代码实现:
import os
import shutil
import tempfile
temp_dir = tempfile.gettempdir()
for item in os.listdir(temp_dir):
if item.startswith("_MEI"):
shutil.rmtree(os.path.join(temp_dir, item))
这段代码会在每次运行时检查TEMP
目录,并删除以_MEI
开头的文件夹。但请注意,这可能会清理其他正在运行的PyInstaller打包程序的临时文件夹,因此最好确保你的应用是独占运行或者有其他机制避免误删。