作者poototo (poototo)
看板Python
标题Re: [问题] MEIPASS - No such file or directory er
时间Tue Jan 25 23:35:10 2022
le大好说,互通有无大家求进步
您看来有一个误解之处是
原PO的状况是,opencc有被打包了,但并不是所有套件下的档案都被自动打包
s2tw.json这个档是原PO要叫pyinstaller去抓来打包进exe的
并不是日後放在exe所在电脑,使用者还要确保自己电脑有这个json档跟opencc
打包成功,exe自己带着走,会当场重新产生json
而重新产生的位置,就是在sys._MEIPASS下
sys._MEIPASS,是每次exe一执行时强加sys的属性
而预设值就是OS的TEMP PATH (通常就是User目录的AppData下)
供 add-file 那些档案在日後每次exe执行时重新产生到_MEIPASS
透过_MEIPASS的设计,exe在任意电脑上执行,
一切就相对於预设TEMP,不用管exe本身所在位置或使用者名称
exe执行结束,TEMP中重新产生的资源档也会被删除
官方说明如下,再讨论
================================================
1.
https://pyinstaller.readthedocs.io/en/stable/usage.html
--runtime-tmpdir PATH
2.
https://pyinstaller.readthedocs.io/en/stable/runtime-information.html
区分是打包後的exe在执行,还是python process在执行
================================================
※ 引述《lepenseur (lepenseur)》之铭言:
: ※ 引述《imhandmore (imhandmore)》之铭言:
: : 我用OpennCC模组制作程式码,我在IDE环境上面可以顺利执行
: : 但等到我用pyinstaller 打包成exe之後就会显示下列错误:
: : Traceback (most recent call last):
: : File "converter2.py", line 20, in <module>
: : File "opencc\opencc.py", line 55, in __init__
: : File "opencc\opencc.py", line 106, in _init_dict
: : FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\Claude\\AppData\\Local\\Temp\\_MEI151842\\opencc\\config\\s2tw.json'
: : [20160] Failed to execute script converter2
: : ----------------------------
: : 我看stackoverflow的文章,加上adddata也是一样
: : 目前苦恼不知道怎麽解决,请各位帮我想个办法,或者请私讯我 我可以提供报酬请你们帮忙解决
: : -----
: : Sent from JPTT on my Google Pixel 3a.
: ----------
: 去年因为工作常常用到 pyinstaller 跟安装精灵开发专案,
: 今天刚好看到有人讨论,所以有点兴趣。
: 也有可能是我观念有错,请不吝指正,让我有机会成长。
: ----------
: : poototo: le大对sys._MEIPASS的动态路径观念要参考一下
: 我觉得 poototo 大大可能太执着在 MEIPASS 这个关键字上。
: 我平常习惯的写法就是
: project_root = Path(sys._MEIPASS) if getattr(sys, 'frozen', False) else
: Path(__file__).absolute().parents[0]
: 先抓出专案路径,接着都用这个路径去动态切换。
: 但原 PO 这个写法,就算改用 sys._MEIPASS,也只能读到该专案的目录而已,抓不到使
: 用者的 AppData 路径,还是会报错。
: ---
: 基本上,整段错误讯息的重点是
: FileNotFoundError: [Errno 2] No such file or directory:
: 'C:\\Users\\Claude\\AppData\\Local\\Temp\\_MEI151842\\opencc\\config\\s2tw.json'
: 这一行。
: 意思是,你的 exe 执行时,在 C:\\Users\\Claude\\AppData\\... 这路径下面读取不到
: s2tw.json 这个档案。
: 这个目录是 Windows 下,每个使用者的应用程式设定,你安装的软体,都有可能在这边
: 储存你需要的设定值或档案。
: 所以,是因为原 PO 的 s2tw.json 档案位置放在 AppData 下,
: 当安装到另外一台电脑时(假设使用者是 John),那他的绝对路径应该依据使用者名
: 称修改成 C:\\Users\\John\\AppData\\...\\s2tw.json
: 这个写法,不仅要根据使用者名称去修改路径,还要请使用者的电脑上安装 opencc,
: 才会有这个档案存在。
: 但原 PO 最近暂时没回覆,也许已经解决问题了。
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 180.177.89.24 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Python/M.1643124914.A.D32.html
※ 编辑: poototo (180.177.89.24 台湾), 01/25/2022 23:45:02
1F:→ lepenseur: 我明白—add-data 的档案会放在包装後目录下 01/26 01:23
2F:→ lepenseur: 但是,他现在执行exe的错误内容,就是去AppData这个目 01/26 01:25
3F:→ lepenseur: 录读取资料,而不是从执行档的目录下(sys._MEIPASS) 01/26 01:25
4F:→ lepenseur: 抓json 01/26 01:25
5F:→ lepenseur: 所以我才说,他应该要想清楚,部署的平台要怎麽安排这 01/26 01:25
6F:→ lepenseur: 些档案放哪里、该怎麽读 01/26 01:25
7F:→ lepenseur: —add-data可以打包没错,但他程式码是从AppData这边 01/26 01:26
8F:→ lepenseur: 抓资料,所以会继续报错 01/26 01:26
9F:→ lepenseur: 你尝试把一个档案只放在AppData,其他目录不能放,然 01/26 01:28
10F:→ lepenseur: 後尝试打包、在另一台电脑上执行看看,应该可以重现这 01/26 01:28
11F:→ lepenseur: 个问题 01/26 01:28
12F:→ lepenseur: 你成功打包opencc没错,东西也在sys._MAIPASS下没错, 01/26 01:30
13F:→ lepenseur: 但你的程式码就跑去AppData这个目录抓资料,所以才出现 01/26 01:30
14F:→ lepenseur: 这个错误提示 01/26 01:30
15F:→ poototo: 1.add-data档案【不会】放在包装後目录下,是在【exe中】 01/26 09:02
16F:→ poototo: 2.exe执行档所在目录 != sys._MEIPASS 01/26 09:02
17F:→ poototo: sys._MEIPASS会指向AppData下的乱数名称目录 01/26 09:03
18F:→ poototo: 如原PO的错误讯息中的路径有个 _MEI151842 01/26 09:03
19F:→ poototo: 这是exe每次执行都会当场造的 01/26 09:03
20F:→ poototo: (所以每次执行每次都会更新一次sys._MEIPASS) 01/26 09:03
21F:→ poototo: import相依套件及add-data的档案都在_MEI151842下解压 01/26 09:03
22F:→ poototo: user无法【事先部署】这些档案,是exe自己【当场部署】 01/26 09:04
23F:→ poototo: 原本opencc.py执行时会去读site-package下opencc下的json 01/26 09:04
24F:→ poototo: 打包exe後,opencc.py的读取起点会换成sys._MEIPASS 01/26 09:04
25F:→ poototo: 原PO只要将json打包【进exe】,指定正确的解压path 01/26 09:04
26F:→ poototo: 而非要求使用者电脑中要有一份json或额外安装相依档案 01/26 09:04
27F:→ poototo: 使用者只要执行exe就好,不必搞环境部署 01/26 09:04
28F:→ lepenseur: 那请问你要如何指定解压到该使用者的AppData 呢? 01/26 16:20
29F:→ lepenseur: 你一直忽略错误讯息里面,去AppData读取资料的这件事, 01/26 16:21
30F:→ lepenseur: 我们一直在鸡同鸭讲 01/26 16:21
31F:→ lepenseur: 而且真的有需要写入资料的话,一般都是直接写安装精灵 01/26 16:22
32F:→ lepenseur: ,安装精灵可以做完这些事情,不会让使用者自己去设定 01/26 16:22
33F:→ lepenseur: 环境 01/26 16:22
34F:→ lepenseur: sys._MAIPASS 我知道如何使用,我也是这样操作的。但现 01/26 16:24
35F:→ lepenseur: 在的情境是,exe执行时尝试去AppData读取资料导致错误 01/26 16:24
36F:→ lepenseur: 另外,pyinstaller 解压执行超慢,一般是小专案才会用 01/26 16:27
37F:→ lepenseur: ,正式的软体几G没办法等你这样解压,建议你了解一下py 01/26 16:27
38F:→ lepenseur: installer产生资料夹的操作 01/26 16:27
39F:→ poototo: add-data就是在指定sys._MEIPASS下的解压路径 01/26 16:28
40F:→ poototo: AppData就是在sys._MEIPASS指向的路径当中 01/26 16:29
41F:→ poototo: 会去读AppData下的资料就是exe的正常行为 01/26 16:30
42F:推 lepenseur: 抱歉,刚刚去翻文件,我懂你的意思了 01/26 16:31
43F:→ lepenseur: 你说的是pyinstaller -F 下的操作情形 01/26 16:32
44F:→ lepenseur: 我说的是 pyinstaller -D 下的操作情形 01/26 16:32
45F:→ poototo: 你的exe还会在user电脑放很多档案才能正常执行? 01/26 16:33
46F:→ lepenseur: 所以你才会说解压档案到_MAIPASS目录下 01/26 16:33
47F:→ poototo: 原PO应该是希望打包成 one file的方式 01/26 16:33
48F:→ lepenseur: 我写的是要部署到客户端电脑的软体,基本上是一整个软 01/26 16:34
49F:→ lepenseur: 体资料夹,档案大小有时候几百M或几G 01/26 16:34
50F:→ lepenseur: 所以都不会使用 onefile 01/26 16:34
51F:→ lepenseur: 长知识了 01/26 16:34
52F:→ lepenseur: 功能稍微多一点,每次开启onefile解压缩就要等超久 01/26 16:36
53F:→ lepenseur: 感谢poo大,让我更了解onefile的运作机制 01/26 16:36
54F:→ poototo: 刚看原PO是用 -F,但我也在想是否可以不要打包python套件 01/26 16:40
55F:→ poototo: import一堆,exe常100M上下,然後执行又解压套件出来 01/26 16:40
56F:推 lepenseur: 原ok原本加上—add-data还是挂,所以我以为他路径设定 01/26 16:42
57F:→ lepenseur: 错,他後面也没出来回覆 01/26 16:42
58F:→ lepenseur: 可能问题已经解决了 01/26 16:42
59F:推 lepenseur: 不打包python套件可能比较难,就是需要用到才import的 01/26 16:47
60F:→ lepenseur: 啊XD 01/26 16:47
61F:→ lepenseur: 我还是觉得onedir的方式比较好用,加上安装精灵,资料 01/26 16:48
62F:→ lepenseur: 夹安装在C槽,桌面建立一个捷径,方便实用 01/26 16:48