我正在创建一个应用程序,我想检查我的计算机是否已经安装了一个应用程序(Example.app,com.example.test)并能够将该应用程序发送到Mac App Store。
我尝试了几件事,比如:
NSString *script = @"try\r tell application \"Finder\" to get application file id \"com.example.test\"\r set appExists to true\r on error\r set appExists to false\r end try";
NSAppleEventDescriptor *result = [self executeScript:script];
return [result booleanValue];
这非常有效,但我一直在阅读Apple在权利文件中不允许Finder的临时例外,以保证应用的安全。
我也尝试了类似的东西,但避免使用Finder:
NSString *script = @"set appID to id of application \"Example\"\r set msg to exists application id appID\r tell application \"Example\" to quit\r return msg";
NSAppleEventDescriptor *result = [self executeScript:script];
return [result booleanValue];
仅当用户拥有应用时才有效,如果没有,则会提示询问应用位置的对话框。 (并在Dock中显示示例图标几毫秒)
我也在尝试一些更为苛刻的解决方案,如:
NSTask *task = [NSTask new];
[task setLaunchPath:@"/bin/bash"];
[task setArguments:@[@"if ls /Applications/Example.app >/dev/null 2>&1; then echo FOUND; else echo NOT FOUND; fi"]];
[task launch];
[task waitUntilExit];
int status = [task terminationStatus];
if (status == 0)
NSLog(@"Task succeeded.");
else
NSLog(@"Task failed.");
但是任务总是失败,我认为命令行的东西永远不会工作(如果是这样的话,无意义的沙盒)。
我一直想放一个按钮(复选框),提示一个对话框以选择App的路径,并检查应用名称是否等于Example,如果是,请选中复选框,然后取消选中是否不是。但我不知道如何提示该对话框。 (如果有可能,我想避免这个解决方案)
我的问题是:
由于
答案 0 :(得分:7)
您是否使用NSWorkspace
尝试了以下内容?:
NSURL *appURL = [[NSWorkspace sharedWorkspace]
URLForApplicationWithBundleIdentifier:@"com.example.test"];
如果结果为nil
,您可以认为启动服务不是“了解”应用程序,无论它位于何处,否则它将返回NSURL
。 (启动服务是CoreServices
伞形框架的一部分,是处理应用程序和文档绑定的框架)。使用Launch Services通常比检查特定路径更好,因为app bundle可以在文件系统中移动但仍然存在。
您发布的AppleScript代码可能与Finder调用上面显示的代码相当:它只是调用Launch Services来查找具有该bundle标识符的应用程序。
答案 1 :(得分:0)
我认为(根据2012年WWDC的自动化会议),您应该使用NSUserScriptTask
。确切地说,您需要子类NSUserAppleScriptTask
,并且您能够在沙箱之外触发用户定义的AppleScript。它将使用XPC服务执行脚本,并使用命令行实用程序osascript
运行脚本。您的应用程序是沙箱,因此可以安装脚本的唯一允许位置是NSApplicationScriptsDirectory
,位于~/Library/Application Scripts/<bundle-id>/
请注意,默认情况下它不是自我定位的应用程序上下文,因此当您需要编写应用程序脚本时,您需要明确告诉应用程序执行操作。因此它不像NSAppleScript
那样运行,它将由应用程序本身NSUserScriptTask
执行,它的子类将在应用程序(沙箱)之外运行。