【macOS】 時代遅れのアプリ配布形式なのか「dmg」vs「zip」

こういう記事を見かけて。

Having a wrapper just to tell you "please drag the app to /Applications" feels like an outdated practice to me.

「アプリを Applications フォルダ にドラッグしてください」とだけ伝えるラッパーがあるのは、時代遅れのやり方のように思います。

かなり同感できるので2つの形式の違いを調べることにしました。

そもそも、ユーザー側から見ると、今のダウンロードな時代に、

ディスクイメージのマウントとかイジェクトとかも分かりづらいのではないかと思ってます。

その他、pkg 形式とか Homebrew とかの話はここでは無視。

 

🤔 Chrome をインストールする場合の手順 ( dmg 形式 )

その時の手順の流れは、


1. .dmgファイルをダウンロードし、
2. ダウンロードしたフォルダを開き、
3. .dmgファイルをマウントし、
3. 2つ目のフォルダーを開くか、サイドバーをオンにし、
4. .app フォルダをアプリケーションフォルダにドラッグし、
5. マウントされた .dmgファイルをイジェクトし、
6. ダウンロードした .dmg ファイルをゴミ箱に捨てる。

となります。

なんか良く考えたら、だるい !!

 

🤔 VSCode をインストールする場合 ( zip 形式 )

手順。


1. .zipをダウンロードして解凍し、
2. ダウンロードしたフォルダを開き、
3. .app フォルダをアプリケーションフォルダにドラッグします。

簡単で良い !!

 

🤔 有名アプリはどっちの形式なのか


dmg 形式
- Chrome
- Firefox
- Gimp
- VLC
- IINA
- LibreOffice
- Keka
- WhatsApp
- Skype


app 形式
- Visual Studio Code
- Telegram
- iStat Menus
- Plex Media Server

dmg 形式のほうが多いです。

 

🤔 みんなの意見

いろいろ言っております。

最終的には、ソフトウェアを .dmg ファイルとして配布するか .zip ファイルとして配布するかの選択は、開発者の好みと、アプリケーションとそのユーザーの特定のニーズによって決まります。

Apple は単純に ZIP 形式を活用することもできたが、そうしないことを選択した。Apple は独自の歴史があるため、一般的に独自の方法で独自のことを行っている。それはそれでよいことだ。Apple が採用しているモデルには利点があり、その利点はより一般的なメカニズムを使用して別の方法で構築することもできたが、物事はそのままでいることもある。

DMG を使用すると、インストール エクスペリエンスが向上します。DMG に背景画像を設定したり、利用規約に同意するための EULA を提供したりできます。「インストールするにはここにドラッグしてください」などの内容の DMG を開くと、実際には背景画像とアプリケーション フォルダーのエイリアスが表示されます。DMG は通常、読み取り専用として配布されるため、ユーザーはアーカイブして後で使用できるように保存し、アプリケーション フォルダーに簡単にドラッグできます。DMG は、ソフトウェア ディスクを購入してコンピューターに挿入し、デスクトップにマウントするエクスペリエンスを模倣しています。DMG には、PKG ファイルまたは prefPane ファイル (設定ベースのアプリ インストーラー) が含まれる場合があり、これらは単独で配布できます。ただし、DMG のカスタマイズ機能は、視覚的なエクスペリエンスをユーザーにアピールしたい開発者にとって魅力的です。

DMG を生成するのがもっと複​​雑でした。なぜなら、DMG を作成するための簡単な開発者スクリプトがなかったからです。誰もが DMG を使用していましたが、今ではスクリプトがあるところでは zip ファイルに移行しています。これもまた歴史の皮肉です。

好みの問題か、.dmg ファイルの作成方法がわからないということだと思います。

ls(1) コマンドを使用してコマンドラインから確認すると、.app ファイルは実際にはファイルではなくディレクトリであることがわかります。したがって、.app ファイルが配布されることは決してありません。それらは何かにアーカイブする必要があります。

.app はファイルではなく、ファイルが入ったディレクトリです。一般的なファイル転送プロトコルで送信したい場合は、そのディレクトリをファイルに変換する必要があります。2 つの明らかな選択肢は、zip ファイルとディスク イメージです。

zip ファイルはシンプルで、ダウンロード フォルダから解凍したアプリをアプリケーション フォルダにコピーするだけです。ただし、ディスク イメージにはいくつかの利点があります。ユーザーにライセンスへの同意を求めるように作成したり、Finder ウィンドウにイメージ背景の形式でブランドを追加したり、複数の部分から成るインストーラを簡単に配置したりできます。

などなど...。

👉 Why are most MacOS applications distributed as .dmg files rather than .zip? - Quora hatena-bookmark

 

🤔 まとめ

いきなりまとめます。

dmg 形式の利点として、


- 「アプリを Applications フォルダ にドラッグしてください」と表示
- カスタム背景
- ライセンス契約、リリースノートの追加

dmg 形式のほうができることが少し多いようです。

しかし、作成手順が面倒なので、

環境に合わせて、以下のツールなどを使うと良さげです。

👉 create-dmg/create-dmg: A shell script to build fancy DMGs hatena-bookmark
👉 create-dmg — Homebrew Formulae hatena-bookmark
👉 dmgbuild · PyPI hatena-bookmark
👉 sindresorhus/create-dmg: Create a good-looking DMG for your macOS app in seconds hatena-bookmark
👉 LinusU/node-appdmg: 💾 Generate your app dmgs hatena-bookmark

ひとつ使って簡単に作成してみました。


まあ、dmg 形式にしとくのが無難なんでしょうね。

 

🤔 参考

以上、以下の issues を見ながらのエントリーでした。

👉 [macOS] Use Drag to Install idiom in published DMG releases · Issue #4062 · transmission/transmission hatena-bookmark

👉 Use .app bundle instead of .dmg file for macOS distribution · Issue #6783 · transmission/transmission hatena-bookmark



【macOS】アプリのインストーラーを create-dmg で作る

macOS アプリを作ったら、

dmg 形式にしてインストールできるようにしましょう。

ツールを使います。


👉 create-dmg/create-dmg: A shell script to build fancy DMGs hatena-bookmark

Homebrew でインストールしました。


brew install create-dmg

👉 create-dmg — Homebrew Formulae hatena-bookmark

するといくつかエラーとなりました。

 

🧑🏻‍💻 execution error: Not authorized to send Apple events to Finder. (-1743)

以下のようなエラーが表示されて.dmgファイルは作成されませんでした。

(途中の一時的なファイルは作成された。)

execution error: Not authorized to send Apple events to Finder. (-1743)

設定から、以下で権限を付与すればいいそうです。


Security & Privacy
  ↓
Automation
  ↓
Terminal (or iTerm)
  ↓
Finder ✅


👉 macOS 11: execution error: Not authorised to send Apple events to Finder. (-1743) · Issue #113 · create-dmg/create-dmg hatena-bookmark

 

🧑🏻‍💻 hdiutil does not support internet-enable. Note it was removed in macOS 10.15.

以下のような警告?のようなものが表示されました。

hdiutil does not support internet-enable. Note it was removed in macOS 10.15.

これは、オプションに、


--no-internet-enable

を付ければ消えました。

👉 hdiutil internet-enable · Issue #76 · create-dmg/create-dmg hatena-bookmark

 

🧑🏻‍💻 まとめ

以上を含めて、必要最小限なオプションで、

以下のように実行することで、

dmg インストーラーを作ることができました。


test -f Sample-Installer.dmg && rm Sample-Installer.dmg
create-dmg \
--window-pos 0 0 \
--icon "Sample.app" 175 125 \
--app-drop-link 325 125 \
--volname "Sample-Installer" \
"Sample-Installer.dmg" \
"Sample 2024-08-05 22-20-23/" \
--no-internet-enable \
--hdiutil-verbose

他にも、オプション記述はたくさんあるので、

さらに調整して使いやすものにしていくことができるようです。

 

🧑🏻‍💻 関連記事



【macOS】 アプリのすっきりアンインストール方法から学ぶ「アプリ関連ファイルの場所」

いまさら調べてみる。まず Apple 公式。


* Lauchpad からアンインストールする

* Finder を使って
  - ゴミ箱にいれる
  - ⌘ ( command ) + ⌫ ( delete )

* アプリ同梱のアンインストールスクリプト

👉 Mac でアプリをアンインストールする - Apple サポート (日本) hatena-bookmark

コマンドラインで。


❯ sudo uninstall file://Applications/Pages.app

👉 How to completely uninstall an app on a Mac and delete all junk files hatena-bookmark

Homebrew のコマンドを使うなら。


❯ brew help uninstall
Usage: brew uninstall, remove, rm [options] installed_formula|installed_cask
[...]

Uninstall a formula or cask.

  -f, --force                      Delete all installed versions of formula.
                                   Uninstall even if cask is not installed,
                                   overwrite existing files and ignore errors
                                   when removing files.
      --zap                        Remove all files associated with a cask.
                                   May remove files which are shared between
                                   applications.
      --ignore-dependencies        Don't fail uninstall, even if formula is a
                                   dependency of any installed formulae.
      --formula, --formulae        Treat all named arguments as formulae.
      --cask, --casks              Treat all named arguments as casks.
  -d, --debug                      Display any debugging information.
  -q, --quiet                      Make some output more quiet.
  -v, --verbose                    Make some output more verbose.
  -h, --help                       Show this message.

実際、今現在、私も使っているが、このアプリがベストに思える。


👉 AppCleaner hatena-bookmark

サードパーティのアプリなのですが、

どのファイルを削除してるのだろうか

と思いました。

 

🤔 手動で完全にアンインストールする方法

実際にはやらないけども、アプリの構造やインストーラのしくみの理解にもつながるはず。

👉 t18n/uninstall-cli: Open-sourced CLI tool to uninstall application on MacOS hatena-bookmark

アプリ(.app)のパス

から

「アプリ名」と「アプリ識別子」

を取得してから、

可能性のあるディレクトリを走査して、

見つけたファイルが削除の対象。

キャッシュやテンポラリなディレクトリも操作しています。


❯ app=/Applications/Numbers.app

❯ /usr/libexec/PlistBuddy -c "Print CFBundleIdentifier" "$app/Contents/Info.plist"
com.apple.iWork.Numbers

❯ echo $(basename $app .app)
Numbers

❯ find "$HOME/Library/Application Scripts" -iname "*com.apple.iWork.Numbers*" -maxdepth 1 -prune
/Users/me/Library/Application Scripts/com.apple.iWork.Numbers
/Users/me/Application Scripts/com.apple.iWork.Numbers.NumbersNotificationServiceExtension

❯ find "$HOME/Library/Application Scripts" -iname "*Numbers*" -maxdepth 1 -prune
/Users/me/Library/Application Scripts/com.apple.iWork.Numbers
/Users/me/Library/Application Scripts/com.apple.iWork.Numbers.NumbersNotificationServiceExtension

❯ echo $(getconf DARWIN_USER_CACHE_DIR | sed "s/\/$//")
/var/folders/2_/860qd2ks5hg6hp26wg2tmtn40000gn/C

❯ echo $(getconf DARWIN_USER_TEMP_DIR | sed "s/\/$//")
/var/folders/2_/860qd2ks5hg6hp26wg2tmtn40000gn/T

このスクリプトもそうですが、すべてのこのへんの記事の元は以下であることが多いようです。

👉 privacy-guides/how-to-clean-uninstall-macos-apps-using-appcleaner-open-source-alternative/app-cleaner.sh at master · sunknudsen/privacy-guides hatena-bookmark

ということで、アプリに関連するファイルの位置は以下だと言えそうです。


locations=(
  "$HOME/Library"
  "$HOME/Library/Application Scripts"
  "$HOME/Library/Application Support"
  "$HOME/Library/Application Support/CrashReporter"
  "$HOME/Library/Containers"
  "$HOME/Library/Caches"
  "$HOME/Library/HTTPStorages"
  "$HOME/Library/Group Containers"
  "$HOME/Library/Internet Plug-Ins"
  "$HOME/Library/LaunchAgents"
  "$HOME/Library/Logs"
  "$HOME/Library/Preferences"
  "$HOME/Library/Preferences/ByHost"
  "$HOME/Library/Saved Application State"
  "$HOME/Library/WebKit"
  "/Library"
  "/Library/Application Support"
  "/Library/Application Support/CrashReporter"
  "/Library/Caches"
  "/Library/Extensions"
  "/Library/Internet Plug-Ins"
  "/Library/LaunchAgents"
  "/Library/LaunchDaemons"
  "/Library/Logs"
  "/Library/Preferences"
  "/Library/PrivilegedHelperTools"
  "/private/var/db/receipts"
  "/usr/local/bin"
  "/usr/local/etc"
  "/usr/local/opt"
  "/usr/local/sbin"
  "/usr/local/share"
  "/usr/local/var"
  $(getconf DARWIN_USER_CACHE_DIR | sed "s/\/$//")
  $(getconf DARWIN_USER_TEMP_DIR | sed "s/\/$//")
)

アプリを特定するのは、上記スクリプトの

「basename」「CFBundleIdentifier」

のようです。

 

🤔 おまけ

SwiftUI で書かれたアンインストールアプリがありました。

👉 Pearcleaner - Product Information, Latest Updates, and Reviews 2024 | Product Hunt hatena-bookmark

現在絶賛公開中の模様。

オープンソースです。

👉 alienator88/Pearcleaner: A free, source-available and fair-code licensed mac app cleaner hatena-bookmark