2015-10-18 33 views
0

我已经实施了基于Apple文档中的'simpleEncrypt'示例的MacOS服务。我正在运行10.9和Xcode 6.2。Services菜单启动错误的应用程序包

我可以构建应用程序包,将其复制到/ Applications,运行一次,并且我的服务将按预期方式出现在其他应用程序的“服务”菜单中。

如果我运行'pbs -dump_pboard',正如我预期的那样,我的应用程序捆绑包的正确路径显示为NSBundlePath。但是,当我从服务菜单中选择我的服务时,MacOS将启动驻留在〜/ Library/Developer/Xcode/Archives中的应用程序的旧副本。

如果我删除旧副本,它将从其他地方运行另一个副本。只有在我删除了具有与我的服务的NSPortName相同的CFBundleName的文件系统上的其他所有应用程序包后,MacOS才会从/ Applications启动正确的一个。当它发生时,该服务正常工作。

如何让MacOS为我的服务可靠地调用正确的应用程序包?

回答

0

在OS X中,应用程序注册为Launch Services,该应用程序负责在请求时执行应用程序,通过双击其应用程序包,通过聚光灯或从您的案例中运行服务菜单。

注册是自动进行的,例如,当应用程序被复制到/ Applications文件夹(不仅仅是复制文件)或甚至仅运行该过程时发生。

通过运行lsregister命令和-dump参数,可以查看已注册应用程序的列表。在OS X 10.10,这将是这样的: -

/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -dump 

当你有相同的应用程序的多个副本,它们的注册资料是一致的,所以发射服务将不会更新其数据库和简单地执行第一次看到应用匹配注册详情。

Apple docs,它表明,您可以注册在代码与功能LSRegisterFSRefLSRegisterURL的应用,使用所述inUpdate布尔参数,或可替换地:

更新的应用程序的修改时间,以确保它将由自动注册实用程序更新

我希望您仍然需要直接运行应用程序,以确保启动服务更新其数据库。对于包的情况,您可以直接导航到应用程序的二进制文件。使用Caculator.app正如你所执行的例子: -

/Applications/Calculator.app/Contents/MacOS/Calculator 

另一种选择,我发现是递增的版本号,或者更彻底,改变其CFBundleIdentifier更新应用程序的Info.plist。

+0

感谢您的回复。 –

+0

在我的情况下,将.app包复制到/ Applications和/或运行它将导致系统重新读取它的.plist(如预期的),这已由服务菜单中更新的NSMenuItem字符串确认。但是,当选择菜单项时,它试图从另一个位置运行服务本身的副本。正如我所提到的,'pbs -dump_pboard'显示了该服务的正确NSBundlePath。但是,如果我运行'lsregister -kill'后跟'lsregister -seed -dump',数据库似乎会得到合理的重建,并且工作正常。 –

+0

是的,它从一个不同的位置运行服务;它是第一次注册的那个。使用'lsregister -kill'重置启动服务数据库和'lsregister -seed'重新扫描并注册找到的应用程序。然而,同一个应用程序的多个版本可能会让人困惑,但至少现在你知道为什么了。 – TheDarkKnight

相关问题