如何将沙盒应用程序添加到登录项

22

如果用户选择该选项,我希望我的应用程序能够自动启动。但在沙盒应用程序中不再允许使用我一直在使用的方法。

我知道我必须创建一个助手来实现这一点。是否有一个简单的教程,附带示例代码可以帮助我完成?

我找到了这个教程,但它对我没有用: http://www.delitestudio.com/2011/10/25/start-dockless-apps-at-login-with-app-sandbox-enabled/

这是一个非常标准的操作,我不明白为什么没有可用的示例项目。

更新:

我上传了一个示例项目:http://ge.tt/6DntY4K/v/0?c


其实我知道,但这为什么很重要呢? - Tibidabo
你能提供更多关于使用教程时出现什么问题的信息吗?例如,是否仍然存在沙盒限制或其他错误消息? - Kevin Grant
好吧,即使沙盒未启用,它也无法正常工作。看起来一切都很好,但当我重新启动计算机时,没有任何东西被启动。 - Tibidabo
3个回答

21

你可以使用这个(免责声明:我的)教程,其中包括示例项目,来让启动时自动启动成功。

更新:我现在已经测试了你上传的示例项目:它可以正常运行,无需进行任何修改,且启动时自动启动成功。唯一的注意事项是AutoStart.app文件必须放置在/Applications或~/Applications文件夹中才能成功地在登录时启动。这是无论应用程序是否被沙盒化都必须要做的。但是,恐怕目前没有官方文档对此进行说明。


你的解决方案可行,但我的在我的电脑上不起作用,原因未知。非常棒的教程,谢谢! - Tibidabo
这个教程非常棒。不过,有没有办法将该项添加到“系统偏好设置”中用户的登录项中呢?目前还没有这个选项。我知道这是可能的,因为我有几个其他来自MAS的应用程序可以做到这一点。 - Joe Workman
您可以使用Launch Services中的LSSharedFileList API内部(文档不太好)的方法来实现。但是,当调用该API的应用程序被沙盒化时,该API将无法工作:使用App Sandbox时,您不能使用LSSharedFileList.h头文件中的函数创建登录项。 这样做的MAS应用程序可能不会被沙盒化。 - Tim
这些要求在以下链接中有详细解释: https://developer.apple.com/library/mac/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html#//apple_ref/doc/uid/TP40011183-CH3-SW29 - lhunath
@Tim - 你的教程适用于几乎所有类型的应用程序,但不是全部,可能是由于iOS的一个bug。我正在创建一个仅为菜单栏应用程序的应用程序,没有窗口。因此,我必须将“Application is Agent”设置为YES,以摆脱其Dock图标。这将防止助手启动主应用程序。如果我将“Application is Agent”设置为NO,则您的教程有效。 - Duck
你写了一篇有用的文章。但我有一个简短的问题。你能帮忙看一下吗?https://stackoverflow.com/questions/47672690/best-practice-to-launch-main-app-from-the-launcher - Nuzhdin Vladimir

11

我刚刚在 Tim的教程 上重新做了大约100次试验。最终我做到了。虽然我发誓第一次尝试时它确实起作用了。 在我的情况下,当我将“启动时启动”开关打开时,我只能在登录后的一秒钟内看到助手应用程序被启动。然后就消失了。 手动启动应用程序,我发现开关被关闭了。

以下是我发现的内容:

  1. 我的捆绑标识符已经在 NSArray *running = [[NSWorkspace sharedWorkspace] runningApplications]列表中。
  2. NSRunningApplication *app (bundle name equal to my app)的状态是:[app isActive] == NO[app isHidden] == NO[app isTerminated] = NO

所以我对代码进行了一些修改,如下所示:

BOOL alreadyRunning = NO;
BOOL isActive = NO; // my modification
NSArray *running = [[NSWorkspace sharedWorkspace] runningApplications];
for (NSRunningApplication *app in running) {

    if ([[app bundleIdentifier] isEqualToString:@"com.mybundleidentifier"]) {
        alreadyRunning = YES;
        isActive = [app isActive]; // my modification
    }
}

if (!alreadyRunning || !isActive) { // my modification
  ....

我的系统信息:Mac OS X 10.8.2,XCODE 4.6。 - Homer Wang
3
isActive = [app...后面加上break; - ahmet alp balkan

1
您可以尝试使用“服务管理框架”。

http://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLoginItems.html#//apple_ref/doc/uid/10000172i-SW5-SW1

根据http://developer.apple.com/library/mac/#documentation/Security/Conceptual/AppSandboxDesignGuide/DesigningYourSandbox/DesigningYourSandbox.html所述...

要为您的沙盒应用程序创建登录项,请使用ServiceManagement/SMLoginItem.h中声明的SMLoginItemSetEnabled函数,如在守护进程和服务编程指南中所述的使用服务管理框架添加登录项

(使用App Sandbox,您不能使用LSSharedFileList.h头文件中的函数创建登录项。例如,您不能使用LSSharedFileListInsertItemURL函数。也不能通过使用LSRegisterURL函数来操纵启动服务的状态)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接