用于在不破坏沙盒的情况下检查外部应用是否存在的代码



我正在制作一个应用程序,我想检查我的计算机是否已经安装了应用程序(Example.app,com.example.test(并能够将该应用程序发送到Mac App Store。

我尝试了几件事,例如:

NSString *script = @"tryr tell application "Finder" to get application file id "com.example.test"r set appExists to truer on errorr set appExists to falser 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 appIDr tell application "Example" to quitr return msg";
NSAppleEventDescriptor *result = [self executeScript:script];
return [result booleanValue];

这仅在用户拥有应用时才有效,如果没有,它将提示一个对话框,询问应用位置。(并在停靠栏中显示示例图标几毫秒(

我也一直在尝试一些更黑客的解决方案,例如:

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.");

但是任务总是失败,我认为命令行的东西永远不会起作用(如果是这样,胡说八道的沙盒(。

我一直在考虑放置一个按钮(复选框(,该按钮会提示对话框以选择应用程序的路径,并检查应用程序名称是否等于示例,如果是,请选中复选框,如果不是,则取消选中。但我不知道如何提示该对话框。(如果可能的话,我想避免这个解决方案(

我的问题是:

  • 是否可以按照沙盒规则知道应用程序是否存在(无需打开它(?
  • 我可以将 Finder 设置为临时例外,然后 Apple 会批准它吗?(解释意图是什么(

谢谢

您是否使用 NSWorkspace 尝试过以下内容?

NSURL *appURL = [[NSWorkspace sharedWorkspace] 
               URLForApplicationWithBundleIdentifier:@"com.example.test"];

如果结果是 nil ,您可以将其视为启动服务不"知道"应用程序,无论它位于何处,否则它将返回NSURL。(启动服务是CoreServices伞框架的一部分,是处理应用程序和文档绑定的框架(。使用启动服务通常是比检查特定路径更好的方法,因为应用程序包可以在文件系统中移动,但仍存在。

您发布的AppleScript代码可能相当于让Finder调用上面显示的代码:它只是调用启动服务以查找具有该捆绑标识符的应用程序。

我认为

(根据 2012 年 WWDC 的自动化会议(您应该使用 NSUserScriptTask .要做到这一点,你需要子类NSUserAppleScriptTask并且你可以在沙箱之外触发用户定义的AppleScript。它将做的是使用 XPC 服务执行脚本,并使用命令行实用程序运行脚本的位置 osascript 。您的应用程序是沙盒式的,因此唯一允许安装脚本的位置是位于 ~/Library/Application Scripts/<bundle-id>/NSApplicationScriptsDirectory

因此

,请注意,默认情况下,应用程序上下文不是自我定位的,因此当您需要编写应用程序脚本时,您需要显式告诉应用程序执行该操作。因此,它不像应用程序本身执行的NSAppleScript那样运行,NSUserScriptTask它的子类将在应用程序(沙盒(之外运行。

最新更新