我有一个名为 FileOpener.app 的应用程序,它具有以下内容:
FileOpener.app
- Contents
Info.plist
- MacOS
- FileOpener
- Resources
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>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>FileOpener</string>
<key>CFBundleIdentifier</key>
<string>com.example.FileOpener</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>FileOpener</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<!-- Document Types -->
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>Test File</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>com.example.testfile</string>
</array>
</dict>
</array>
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeIdentifier</key>
<string>com.example.testfile</string>
<key>UTTypeDescription</key>
<string>Test File</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>testfile</string>
</array>
<key>public.mime-type</key>
<string>application/x-testfile</string>
</dict>
</dict>
</array>
<key>NSDocumentsFolderUsageDescription</key>
<string>Description goes here</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>file</string>
</array>
</dict>
</plist>
我有一些超级简单的 Rust 代码:
fn log_message(message: &str) {
let mut log_file = OpenOptions::new()
.create(true)
.append(true)
.open("/tmp/fileopener.log")
.unwrap();
writeln!(log_file, "{}", message).unwrap();
}
fn main() -> notify::Result<()> {
let args: Vec<String> = env::args().collect();
log_message(&format!("Received arguments: {:?}", args));
if args.len() != 2 {
eprintln!("Usage: {} <path to .testfile file>", args[0]);
log_message("Incorrect number of arguments.");
return Ok(());
}
}
因此,每当调用二进制文件时,它都会将参数记录到 tmp 文件中,并期望将文件路径的辅助参数传递到其中。
如果我运行 ./FileOpener/Contents/MacOS/FileOpener ./path/to/file.testfile
参数传入正确。
如果我尝试将 file.testfile 拖到 FileOpener.app 上,file.testfile 的路径不会作为参数传入,唯一的 arg 是 FileOpener.app 的路径。如果我尝试双击 file.testfile,FileOpener.app 会打开,但 file.testfile 的路径不会作为参数传入,只有 arg 是 FileOpener.app 的路径。
我想要做的是注册 .testfile 扩展名,以便在双击时打开 FileOpener.app,并将单击(或拖动)文件的路径作为第二个参数传递。
我还尝试过代码签名,
sudo codesign --deep --force --sign - ./FileOpener.app
,将其复制到/Applications中,通过安全性启用全磁盘访问等。我需要的辅助参数(意味着所单击的文件的路径)永远不会被传递在.
macOS 不会通过在 args 中传递文档来打开文档。相反,在应用程序的事件循环启动后,它会收到打开文件的事件。
(请注意,macOS 与 Windows 和 Linux 不同,但与 Android 和 iOS 一样,默认情况下“每个应用程序只有一个进程”;因此,在应用程序已经运行时,需要类似这种机制来处理打开的文件。但是, macOS 自从被称为“Macintosh 系统”以来就一直以这种方式工作,并且没有 Unix,也根本没有 argv
。)
是一个看起来可以做到这一点的库,但我自己还没有使用过它。