063d58aa by 柴进

:sparkles: 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>
1 parent 9571a621
...@@ -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 "================================"
......