DMG 加 drag-to-install 布局 (.app 左, Applications 右)
双击挂载后, Finder 窗口显示两个图标并排, 用户直接把 ZB100ImageGenerator.app 拖到 Applications 快捷方式上即可安装, 不用讲解路径, 符合 macOS 标准分发体验. 实现: - 先 staging: 把 .app 放入临时目录, 同级建 Applications 软链 - hdiutil create UDRW 可写镜像 - 挂载 -> AppleScript 设置窗口大小/图标位置/视图样式 - 卸载 -> hdiutil convert UDZO 压缩成只读分发包 - osascript 失败不中断 (防 Finder 自动化权限未授予), DMG 仍可用 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Showing
1 changed file
with
56 additions
and
7 deletions
| ... | @@ -82,18 +82,67 @@ if [ ! -d "dist/ZB100ImageGenerator.app" ]; then | ... | @@ -82,18 +82,67 @@ if [ ! -d "dist/ZB100ImageGenerator.app" ]; then |
| 82 | exit 1 | 82 | exit 1 |
| 83 | fi | 83 | fi |
| 84 | 84 | ||
| 85 | # 打包 DMG 作为分发格式 | 85 | # 打包 DMG 作为分发格式 (带 drag-to-install 布局) |
| 86 | # 为什么必须: .app 里有嵌套 symlink (PIL/.dylibs -> __dot__dylibs), | 86 | # 为什么必须: .app 里有嵌套 symlink (PIL/.dylibs -> __dot__dylibs), |
| 87 | # cp/NAS/SMB/微信 等传输方式可能吞掉内层 symlink 导致目标机启动失败. | 87 | # cp/NAS/SMB/微信 等传输方式可能吞掉内层 symlink 导致目标机启动失败. |
| 88 | # .dmg 是 HFS+ 镜像, symlink 原样保存, 用户挂载拖拽即用. | 88 | # .dmg 是 HFS+ 镜像, symlink 原样保存, 用户挂载拖拽即用. |
| 89 | echo "Creating DMG..." | 89 | echo "Creating DMG with drag-to-install layout..." |
| 90 | DMG_PATH="dist/ZB100ImageGenerator.dmg" | 90 | DMG_PATH="dist/ZB100ImageGenerator.dmg" |
| 91 | rm -f "$DMG_PATH" | 91 | TMP_DMG="dist/.tmp_rw.dmg" |
| 92 | STAGE="dist/.dmg_stage" | ||
| 93 | VOL_NAME="ZB100ImageGenerator" | ||
| 94 | |||
| 95 | # 1. 准备 staging: .app + Applications 快捷方式 | ||
| 96 | rm -rf "$STAGE" | ||
| 97 | mkdir -p "$STAGE" | ||
| 98 | cp -R "dist/ZB100ImageGenerator.app" "$STAGE/" | ||
| 99 | ln -s /Applications "$STAGE/Applications" | ||
| 100 | |||
| 101 | # 2. 先卸载可能残留的同名卷, 防止上次失败留下的挂载 | ||
| 102 | hdiutil detach "/Volumes/$VOL_NAME" -force >/dev/null 2>&1 || true | ||
| 103 | |||
| 104 | # 3. 创建可写 DMG (UDRW), 便于随后调整窗口布局 | ||
| 105 | rm -f "$TMP_DMG" "$DMG_PATH" | ||
| 92 | hdiutil create \ | 106 | hdiutil create \ |
| 93 | -volname "ZB100ImageGenerator" \ | 107 | -volname "$VOL_NAME" \ |
| 94 | -srcfolder "dist/ZB100ImageGenerator.app" \ | 108 | -srcfolder "$STAGE" \ |
| 95 | -ov -format UDZO \ | 109 | -ov -format UDRW \ |
| 96 | "$DMG_PATH" | 110 | "$TMP_DMG" |
| 111 | |||
| 112 | # 4. 挂载并用 AppleScript 布置窗口 (.app 在左, Applications 在右) | ||
| 113 | MOUNT_POINT="/Volumes/$VOL_NAME" | ||
| 114 | hdiutil attach "$TMP_DMG" -readwrite -noverify -noautoopen >/dev/null | ||
| 115 | |||
| 116 | # osascript 失败不致命 (可能因 Finder 自动化权限), DMG 仍然可用, 只是没布局 | ||
| 117 | osascript <<OSASCRIPT_EOF || echo "Warning: Finder 布局失败 (可能需要授予 Finder 自动化权限), DMG 仍可用" | ||
| 118 | tell application "Finder" | ||
| 119 | tell disk "$VOL_NAME" | ||
| 120 | open | ||
| 121 | set current view of container window to icon view | ||
| 122 | set toolbar visible of container window to false | ||
| 123 | set statusbar visible of container window to false | ||
| 124 | set the bounds of container window to {200, 120, 800, 470} | ||
| 125 | set theViewOptions to the icon view options of container window | ||
| 126 | set arrangement of theViewOptions to not arranged | ||
| 127 | set icon size of theViewOptions to 128 | ||
| 128 | set position of item "ZB100ImageGenerator.app" of container window to {160, 170} | ||
| 129 | set position of item "Applications" of container window to {440, 170} | ||
| 130 | update without registering applications | ||
| 131 | delay 1 | ||
| 132 | close | ||
| 133 | end tell | ||
| 134 | end tell | ||
| 135 | OSASCRIPT_EOF | ||
| 136 | |||
| 137 | sync | ||
| 138 | hdiutil detach "$MOUNT_POINT" -force >/dev/null | ||
| 139 | |||
| 140 | # 5. 压缩成最终只读 DMG | ||
| 141 | hdiutil convert "$TMP_DMG" -format UDZO -imagekey zlib-level=9 -o "$DMG_PATH" >/dev/null | ||
| 142 | |||
| 143 | # 6. 清理临时 | ||
| 144 | rm -f "$TMP_DMG" | ||
| 145 | rm -rf "$STAGE" | ||
| 97 | 146 | ||
| 98 | if [ ! -f "$DMG_PATH" ]; then | 147 | if [ ! -f "$DMG_PATH" ]; then |
| 99 | echo "================================" | 148 | echo "================================" | ... | ... |
-
Please register or sign in to post a comment