如何在Mac上程序化构建支持「打开方式」的应用程序?
程序化封装Bash脚本为支持Mac「打开方式」的应用
我完全懂你的需求——不想每次手动用Automator打包,而是要通过代码/命令行的方式快速生成能关联文件、支持「打开方式」的Mac应用。下面是一套可靠的程序化实现方案,全程可以自动化完成:
核心思路
Mac的.app本质就是一个标准化的目录结构,只要正确配置Info.plist(定义应用的文件关联、启动逻辑),再把你的bash脚本和启动器打包进去,就能实现和Automator创建的应用一样的效果,而且全程用命令行就能搞定。
步骤分解
1. 创建基础的.app目录结构
先在终端里用命令生成标准应用目录(替换MyCustomHandler为你的应用名称):
APP_NAME="MyCustomHandler" mkdir -p "${APP_NAME}.app/Contents/MacOS" mkdir -p "${APP_NAME}.app/Contents/Resources"
2. 编写启动器脚本(替代Automator的运行脚本动作)
在Contents/MacOS目录下创建可执行的启动脚本(比如命名为main),它会接收系统传递的文件路径参数(就是用户通过「打开方式」选中的文件),然后调用你的核心业务脚本:
#!/bin/bash # 接收打开的文件路径参数 FILES="$@" # 替换成你的具体业务逻辑,比如调用核心处理脚本 /path/to/your/core-script.sh "$FILES" # 可选:用osascript给用户弹出处理完成提示 # osascript -e 'display notification "处理完成" with title "你的应用名称"'
给脚本添加执行权限:
chmod +x "${APP_NAME}.app/Contents/MacOS/main"
3. 配置Info.plist(关键:设置文件关联)
这是最核心的部分,Info.plist定义了应用能处理的文件类型,让系统知道什么时候把它放到「打开方式」列表里。在Contents目录下创建Info.plist文件,内容如下(根据需求修改占位符):
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleDisplayName</key> <string>MyCustomHandler</string> <!-- 应用显示名称 --> <key>CFBundleExecutable</key> <string>main</string> <!-- 指向MacOS目录下的启动脚本 --> <key>CFBundleIdentifier</key> <string>com.yourdomain.MyCustomHandler</string> <!-- 唯一标识符,自定义 --> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> <string>MyCustomHandler</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> <string>1.0</string> <key>CFBundleVersion</key> <string>1</string> <!-- 关键:定义支持的文件类型 --> <key>CFBundleDocumentTypes</key> <array> <dict> <key>CFBundleTypeExtensions</key> <array> <string>txt</string> <!-- 你要处理的文件扩展名,可添加多个 --> <string>md</string> </array> <key>CFBundleTypeMIMETypes</key> <array> <string>text/plain</string> <!-- 对应MIME类型 --> <string>text/markdown</string> </array> <key>CFBundleTypeName</key> <string>Text Files</string> <key>CFBundleTypeRole</key> <string>Editor</string> <!-- 角色:Editor/Viewer等 --> </dict> </array> </dict> </plist>
4. 可选:添加应用图标
把你的.icns图标文件放到Contents/Resources目录下,然后在Info.plist里添加一行:
<key>CFBundleIconFile</key> <string>YourIcon.icns</string>
5. 注册应用到系统
运行以下命令让系统刷新应用信息,这样你的应用就会出现在「打开方式」列表里:
open "${APP_NAME}.app" # 或者用lsregister强制刷新系统应用缓存 /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -f "${APP_NAME}.app"
一键自动化打包脚本
为了更高效,你可以把上面的步骤写成一个bash脚本,修改开头的参数就能一键生成应用:
#!/bin/bash APP_NAME="MyCustomHandler" BUNDLE_ID="com.yourdomain.MyCustomHandler" SUPPORTED_EXTENSIONS=("txt" "md") SUPPORTED_MIMES=("text/plain" "text/markdown") CORE_SCRIPT="/path/to/your/core-script.sh" # 创建目录结构 mkdir -p "${APP_NAME}.app/Contents/MacOS" mkdir -p "${APP_NAME}.app/Contents/Resources" # 写入启动脚本 cat > "${APP_NAME}.app/Contents/MacOS/main" << EOF #!/bin/bash FILES="\$@" ${CORE_SCRIPT} "\$FILES" EOF chmod +x "${APP_NAME}.app/Contents/MacOS/main" # 生成Info.plist cat > "${APP_NAME}.app/Contents/Info.plist" << EOF <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleDisplayName</key> <string>${APP_NAME}</string> <key>CFBundleExecutable</key> <string>main</string> <key>CFBundleIdentifier</key> <string>${BUNDLE_ID}</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> <string>${APP_NAME}</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> <string>1.0</string> <key>CFBundleVersion</key> <string>1</string> <key>CFBundleDocumentTypes</key> <array> <dict> <key>CFBundleTypeExtensions</key> <array> EOF # 写入支持的扩展名 for ext in "${SUPPORTED_EXTENSIONS[@]}"; do echo " <string>${ext}</string>" >> "${APP_NAME}.app/Contents/Info.plist" done cat >> "${APP_NAME}.app/Contents/Info.plist" << EOF </array> <key>CFBundleTypeMIMETypes</key> <array> EOF # 写入支持的MIME类型 for mime in "${SUPPORTED_MIMES[@]}"; do echo " <string>${mime}</string>" >> "${APP_NAME}.app/Contents/Info.plist" done cat >> "${APP_NAME}.app/Contents/Info.plist" << EOF </array> <key>CFBundleTypeName</key> <string>Custom Files</string> <key>CFBundleTypeRole</key> <string>Editor</string> </dict> </array> </dict> </plist> EOF # 注册应用 open "${APP_NAME}.app" echo "应用${APP_NAME}.app已生成并注册!"
注意事项
- 确保你的核心bash脚本有执行权限,并且路径配置正确
- 处理带特殊字符的文件路径时,启动脚本里的变量要始终用双引号包裹
- 如果想避免Gatekeeper警告,可以用
codesign命令签名应用:codesign -s - "${APP_NAME}.app"
内容的提问来源于stack exchange,提问作者Brett Zamir
相关产品推荐
相关产品推荐

