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
exit 1
fi
# 打包 DMG 作为分发格式
# 打包 DMG 作为分发格式 (带 drag-to-install 布局)
# 为什么必须: .app 里有嵌套 symlink (PIL/.dylibs -> __dot__dylibs),
# cp/NAS/SMB/微信 等传输方式可能吞掉内层 symlink 导致目标机启动失败.
# .dmg 是 HFS+ 镜像, symlink 原样保存, 用户挂载拖拽即用.
echo "Creating DMG..."
echo "Creating DMG with drag-to-install layout..."
DMG_PATH="dist/ZB100ImageGenerator.dmg"
rm -f "$DMG_PATH"
TMP_DMG="dist/.tmp_rw.dmg"
STAGE="dist/.dmg_stage"
VOL_NAME="ZB100ImageGenerator"
# 1. 准备 staging: .app + Applications 快捷方式
rm -rf "$STAGE"
mkdir -p "$STAGE"
cp -R "dist/ZB100ImageGenerator.app" "$STAGE/"
ln -s /Applications "$STAGE/Applications"
# 2. 先卸载可能残留的同名卷, 防止上次失败留下的挂载
hdiutil detach "/Volumes/$VOL_NAME" -force >/dev/null 2>&1 || true
# 3. 创建可写 DMG (UDRW), 便于随后调整窗口布局
rm -f "$TMP_DMG" "$DMG_PATH"
hdiutil create \
-volname "ZB100ImageGenerator" \
-srcfolder "dist/ZB100ImageGenerator.app" \
-ov -format UDZO \
"$DMG_PATH"
-volname "$VOL_NAME" \
-srcfolder "$STAGE" \
-ov -format UDRW \
"$TMP_DMG"
# 4. 挂载并用 AppleScript 布置窗口 (.app 在左, Applications 在右)
MOUNT_POINT="/Volumes/$VOL_NAME"
hdiutil attach "$TMP_DMG" -readwrite -noverify -noautoopen >/dev/null
# osascript 失败不致命 (可能因 Finder 自动化权限), DMG 仍然可用, 只是没布局
osascript <<OSASCRIPT_EOF || echo "Warning: Finder 布局失败 (可能需要授予 Finder 自动化权限), DMG 仍可用"
tell application "Finder"
tell disk "$VOL_NAME"
open
set current view of container window to icon view
set toolbar visible of container window to false
set statusbar visible of container window to false
set the bounds of container window to {200, 120, 800, 470}
set theViewOptions to the icon view options of container window
set arrangement of theViewOptions to not arranged
set icon size of theViewOptions to 128
set position of item "ZB100ImageGenerator.app" of container window to {160, 170}
set position of item "Applications" of container window to {440, 170}
update without registering applications
delay 1
close
end tell
end tell
OSASCRIPT_EOF
sync
hdiutil detach "$MOUNT_POINT" -force >/dev/null
# 5. 压缩成最终只读 DMG
hdiutil convert "$TMP_DMG" -format UDZO -imagekey zlib-level=9 -o "$DMG_PATH" >/dev/null
# 6. 清理临时
rm -f "$TMP_DMG"
rm -rf "$STAGE"
if [ ! -f "$DMG_PATH" ]; then
echo "================================"
......