用 electron-builder 打包成 Windows exe
摘要: 加上 electron-builder 設定,`npm run dist` 產出 NSIS 安裝檔與免安裝版,並修正打包後才會出現的路徑問題。 根本原因: 原本三處路徑都假設程式是攤在資料夾裡跑的,打包成 asar 後會壞: 1. hook 腳本路徑會落在 app.asar 內,而 Claude Code 是用 `node <路徑>` 執行它,node 讀不到 asar 裡的檔案,hook 會直接失敗。 2. pets 資料夾同樣在 asar 內,使用者無法自己丟寵物進去,選單「開啟寵物資料夾」也開不起來。 3. 開機自動啟動寫入的是 `electron.exe + 專案路徑`,打包後沒有 node_modules,登錄值會指向不存在的檔案。 影響: 沒有可散佈的執行檔;直接打包的話 hook、換寵物、開機啟動三個功能都會壞掉。 修法: - 新增 lib/paths.js:unpacked() 把 app.asar 換成 app.asar.unpacked,isPackaged() 以 process.defaultApp 判斷是否為打包版。 - build.asarUnpack 把 hook/ 與 pets/ 解到 asar 外,hooks-installer 與 main.js 的 PETS_DIR 都改走 unpacked()。 - autostart 打包後改用 process.execPath,並跳過開發版才需要的 electron.exe 存在檢查。 - NSIS 設為 per-user、可改安裝路徑、建立桌面與開始選單捷徑,解除安裝不刪 ~/.claude-pet。 - 新增 build/icon.ico(16–256,七種尺寸),取自小念 spritesheet 第 0 列第 6 欄的頭肩方形裁切。 - dist/ 加入 .gitignore;README 補上「打包成 exe」一節與安裝檔的使用方式。 驗證: 以 ELECTRON_RUN_AS_NODE 執行打包後的 exe(不開視窗)載入打包內的 lib,確認 isPackaged 為 true、hook 路徑指到 app.asar.unpacked 且檔案存在、autostart 指到 exe 本身、pets 掃得到 xiao-nian、renderer 讀得到 asar 內的 index.html;另確認 exe 版本資訊與七種尺寸圖示皆已嵌入。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
- [設定檔](#設定檔)
|
||||
- [架構與檔案](#架構與檔案)
|
||||
- [HTTP API](#http-api)
|
||||
- [打包成 exe](#打包成-exe)
|
||||
- [疑難排解](#疑難排解)
|
||||
- [移除](#移除)
|
||||
|
||||
@@ -50,6 +51,12 @@
|
||||
|
||||
## 快速開始
|
||||
|
||||
### 用安裝檔(一般使用)
|
||||
|
||||
執行 `dist\Claude Pet-<版本>-setup.exe`(見[打包成 exe](#打包成-exe)),裝在 `%LOCALAPPDATA%\Programs\Claude Pet`,不需要系統管理員權限。裝完從開始選單開啟,再用系統匣選單的 **Claude Code hooks → 安裝** 接上 Claude Code。
|
||||
|
||||
### 從原始碼跑(開發)
|
||||
|
||||
```powershell
|
||||
cd E:\Project\Test\AI\Claude\claude-pet
|
||||
npm install
|
||||
@@ -200,10 +207,12 @@ Claude Code ──hook(stdin JSON)──▶ hook/claude-pet-hook.js ──PO
|
||||
| `renderer/index.html`、`style.css` | 版面與氣泡樣式(CSP 僅允許 self / data:) |
|
||||
| `hook/claude-pet-hook.js` | Claude Code hook 端:讀 stdin → 擷取欄位 → POST;800 ms 逾時、永遠 exit 0 |
|
||||
| `lib/hooks-installer.js` | 安全地合併 / 移除 `~/.claude/settings.json` 的 hooks(保留其他設定與其他 hooks,先備份) |
|
||||
| `lib/autostart.js` | `HKCU\Software\Microsoft\Windows\CurrentVersion\Run\ClaudePet` 登錄值 |
|
||||
| `lib/autostart.js` | `HKCU\Software\Microsoft\Windows\CurrentVersion\Run\ClaudePet` 登錄值;開發時指向 `electron.exe + 專案路徑`,打包後直接指向那顆 exe |
|
||||
| `lib/paths.js` | 開發/打包兩種情境的路徑解析(`app.asar` → `app.asar.unpacked`、是否為打包版) |
|
||||
| `scripts/*.js` | 上述兩者的 CLI 包裝 |
|
||||
| `pets/` | 內附寵物 |
|
||||
| `docs/` | README 用圖 |
|
||||
| `build/icon.ico` | exe 與安裝檔的圖示,取自小念 spritesheet 第 0 列第 6 欄(中立正面)的頭肩方形裁切 |
|
||||
|
||||
設計重點:
|
||||
|
||||
@@ -257,6 +266,30 @@ curl http://127.0.0.1:17333/state
|
||||
|
||||
也可以送 `{"event":"__test","anim":"waiting"}`(`idle|running|waiting|review|failed|jumping|waving|clear`)直接指定動畫,與選單「動作測試」相同。
|
||||
|
||||
## 打包成 exe
|
||||
|
||||
```powershell
|
||||
npm run dist # 安裝檔 + 免安裝版
|
||||
npm run pack # 只產免安裝版,快很多,開發時驗證用
|
||||
```
|
||||
|
||||
產物在 `dist\`:
|
||||
|
||||
| 檔案 | 說明 |
|
||||
|---|---|
|
||||
| `Claude Pet-<版本>-setup.exe` | NSIS 安裝檔(約 100 MB)。per-user 安裝、不需要系統管理員權限,預設裝到 `%LOCALAPPDATA%\Programs\Claude Pet`,可自選路徑,會建立桌面與開始選單捷徑 |
|
||||
| `win-unpacked\Claude Pet.exe` | 免安裝版,整個資料夾複製走就能直接執行 |
|
||||
|
||||
第一次建置時 electron-builder 會從 GitHub 抓 NSIS 與相關工具到 `%LOCALAPPDATA%\electron-builder\Cache`,需要網路,之後就會走快取。
|
||||
|
||||
**打包後和原始碼跑有三個地方不一樣**(都已經處理好,改程式時要留意):
|
||||
|
||||
- **`hook/` 和 `pets/` 不放進 asar**(`build.asarUnpack`)。前者是因為 Claude Code 用 `node <路徑>` 執行 hook,而 node 讀不到 asar 裡的檔案;後者是因為使用者要能自己丟寵物進去、選單「開啟寵物資料夾」也要打得開。程式裡由 `lib/paths.js` 的 `unpacked()` 把 `app.asar` 換成 `app.asar.unpacked`。
|
||||
- **開機自動啟動**寫入的指令是那顆 exe 本身(`process.execPath`),不再是 `electron.exe + 專案路徑`。判斷方式是 `lib/paths.js` 的 `isPackaged()`。
|
||||
- **hook 指令仍然需要 `node` 在 PATH 裡**。安裝路徑含空白(`Claude Pet`)時會自動加引號。
|
||||
|
||||
換圖示就換掉 `build/icon.ico`(要含 256×256)。目前這顆是從 `pets/xiao-nian/spritesheet.webp` 第 0 列第 6 欄(中立正面)取頭肩方形裁切產生的。
|
||||
|
||||
## 疑難排解
|
||||
|
||||
### Electron 裝完沒有 `electron.exe`
|
||||
@@ -290,12 +323,14 @@ npm config set allow-scripts=@anthropic-ai/claude-code,electron --location=user
|
||||
|
||||
## 移除
|
||||
|
||||
先在系統匣選單關掉 **開機自動啟動**、並用 **Claude Code hooks → 移除** 拆掉 hooks,然後結束程式。從原始碼跑的話也可以下指令:
|
||||
|
||||
```powershell
|
||||
npm run hooks:uninstall # 從 ~/.claude/settings.json 移除所有 Claude Pet hook(先備份)
|
||||
npm run autostart:uninstall # 移除開機啟動登錄值
|
||||
```
|
||||
|
||||
然後刪掉專案資料夾與 `%USERPROFILE%\.claude-pet\` 即可。
|
||||
裝過安裝檔的話,到「設定 → 應用程式 → 已安裝的應用程式」移除 **Claude Pet**(解除安裝不會動到 `%USERPROFILE%\.claude-pet\`)。最後刪掉專案資料夾與 `%USERPROFILE%\.claude-pet\` 即可。
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user