作者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/m.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