本文翻译整理自:Launch Services Programming Guide
https://developer.apple.com/library/archive/documentation/Carbon/Conceptual/LaunchServicesConcepts/LSCIntro/LSCIntro.html#//apple_ref/doc/uid/TP30000999-CH201-TP1
文章目录
- 一、导言
- 谁应该阅读此文档
- 本文件的组织
- 二、启动服务概念
- 1、项目识别
- 2、项目信息
- 3、启动服务数据库
- 启动服务的属性列表键
- 文档类型
- URL 类型
- 应用角色
- 4、申请注册
- 5、开放式运营
- Opening 应用
- Opening 文件
- 打开URL
- 启动选项
- 同步和异步启动
- 6、用户指定的绑定首选项
- 选择文件的绑定偏好设置
- 为URL选择绑定首选项
- 7、首选应用
- 首选文件申请
- URL的首选应用程序
- 三、启动服务任务
- 1、开幕项目
- 按文件系统参考打开项目
- 按URL打开项目
- 2、查找项目的首选应用
- 3、测试应用程序是否可以打开项目
- 4、注册应用程序
- 5、获取有关项目的信息
一、导言
Launch Services是一种API,它使正在运行的应用程序能够以类似于Finder或Dock的方式打开其他应用程序或其文档文件或URL(统一资源定位器)。
使用Launch Services,应用程序可以执行以下任务:
- 打开(启动或激活)另一个应用程序
- 在另一个应用程序中打开文档或URL
- 确定打开给定文档或URL的首选应用程序
- 注册有关应用程序能够打开的文档文件和URL类型的信息
- 获取用于在屏幕上显示文件或URL的适当信息,例如其图标、显示名称和类型字符串
- 维护和更新最近项目菜单的内容
尽管这些服务中的大多数通常由Finder执行,但其他应用程序也可能发现它们对于打开电子邮件附件、跟踪嵌入在文档中的URL、运行辅助应用程序或打开由其他应用程序创建或需要查看或编辑的嵌入式文档组件等目的很有用。
Launch Services的许多功能以前是由桌面管理器提供的。
然而,随着Mac应用程序包的出现,桌面管理器已经失去了它的有用性,因为它不了解捆绑的应用程序,只是忽略了它们。
同样,Launch Services处理URL的功能以前是通过Internet Config API实现的。
Launch Services用一个提供类似功能但旨在在OS X环境中正常运行的新API取代并取代了桌面管理器和Internet Config。
启动服务是专门为避免应用程序要求Finder为其打开应用程序、文档或URL而创建的。
过去,以类似于Finder的方式打开此类项目需要了解多个API,包括桌面管理器、文件管理器、翻译管理器、Internet配置、进程管理器和Apple事件管理器。
Finder还隐含了解桌面数据库和其他地方无法确定打开给定文档的正确应用程序的其他信息。
Launch Services从Finder中删除了这些专业知识,并将其隔离在一个可用于任何应用程序的单一、简单的API中。
OS X Finder根据用户的请求使用Launch Services打开应用程序、文档和URL。
由于Finder除了调用Launch Services之外不做任何额外的处理,因此任何出于这些目的使用Launch Services的客户端都保证与Finder本身的行为相同。
谁应该阅读此文档
本文档面向应用程序需要打开其他应用程序、打开属于它们的文档文件或URL,或以类似于Finder的方式在屏幕上显示文件或URL的所有开发人员。
有关Launch Services API的更多详细信息,请参阅相关文档 Launch Services参考 ,其中提供了对Launch Services函数、数据类型、常量和结果代码的全面描述。
本文件的组织
本文档有以下章节:
- 启动服务概念从开发人员和用户的角度介绍了启动服务API的基本概念。
- 启动服务任务说明如何使用启动服务在应用程序中执行常见任务。
- 术语表定义了与启动服务及其操作相关的各种术语。
二、启动服务概念
本章向开发人员和用户介绍有关Launch Services及其API的基本信息。
1、项目识别
通常,要操作的项目(例如应用程序、文档或文件夹)可以通过以下两种方式之一识别到Launch Services:
- 使用文件系统引用(
FSRef
)指定驻留在本地或远程文件系统卷上的文件 - 使用Core Foundation URL引用(
CFURL
)指定URL(统一资源定位器),通常(尽管不一定)表示要通过Internet访问的项目
许多Launch Services操作由成对的相关函数实现,一个接受文件系统引用作为参数,另一个接受URL引用:例如,可以使用LSGetApplicationForItem
或LSGetApplicationForURL
函数找到打开项目的首选应用程序。
此外,某些启动服务功能不适用于特定的单个项目,而是适用于由某些识别特征定义的项目系列。
这些特征可以包括:
- 四个字符的文件类型代码
- 四个字符的创建者签名
- 文件扩展名
- MIME(多用途Internet邮件扩展)类型
例如,Launch Services函数LSGetApplicationForInfo
查找由文件类型、创建者签名、文件扩展名或这些特征的任意组合定义的文档系列的首选应用程序;LSCopyApplicationForMIMEType
函数查找具有指定MIME类型的项目的首选应用程序。
注意: 在OS X 10.6及更高版本中,Launch Services在将文档绑定到应用程序时不再考虑文件创建者签名。
当创建者签名附加到文档时,Launch Services会忽略它。
此外,函数LSCopyKindStringForTypeInfo
和LSGetApplicationForInfo
忽略包含创建者签名的参数。
2、项目信息
某些Launch Services函数返回有关项目或项目系列的请求信息。
这可以包括:
- 项目的文件类型
- 项目的创建者签名
- 项目的文件扩展名
- 项目的显示名称:用于向用户显示其名称的字符串(例如在Finder或Dock中)
- 项目的*种类字符串:*用于描述其一般性质的字符串(例如,在Finder的获取信息窗口或Finder列表视图的种类列中),例如
Application
、Folder
、Alias
、JPEG Picture
、QuickTime Movie
或FrameMaker Document
- 描述项目各种属性的标志,包括:
- 它是一个普通文件(而不是,例如,目录、卷或UNIX符号链接)吗?
- 它是可执行的应用程序吗?
- 如果是应用程序,它可以在OS X中原生运行吗?
- 如果是应用程序,它是否需要Classic仿真环境?
- 如果一个应用程序可以在本地或经典环境中运行,它更喜欢一种环境还是另一种环境?
- 它是一个可编写脚本的应用程序吗?
- 它是容器(例如目录、包或卷)吗?
- 是打包目录吗?
- 是卷的根目录吗?
- 是化名吗?
- 它是UNIX符号链接吗?
- 它是否不可见(即不在Finder中显示给用户)?
- 它是否有隐藏的文件扩展名?
3、启动服务数据库
Launch Services维护着一个中央数据结构,即Launch Services数据库,其中记录了关于应用程序的所有相关信息以及它们能够打开的文档文件和URL的类型。
每当系统知道一个新应用程序时(例如,当用户将它从安装磁盘拖到Applications文件夹中时),该应用程序就会注册到Launch Services,该应用程序会将有关该应用程序的所需信息复制到其数据库中。
然后,Launch Services可以使用这些信息来确定打开给定文档文件或URL的首选应用程序。
启动服务的属性列表键
Launch Services从应用程序的捆绑信息属性列表(Info.plist
)中获取它需要的关于应用程序的信息,或者在单文件应用程序的情况下,从应用程序资源分支中的'plst'
资源中获取。
表1-1显示了相关的键。
(有关这些和其他属性列表键的更多详细信息,请参阅 运行时配置指南 。)
Table 1-1 Property-list keys related to Launch Services
钥匙 | 类型 | 描述 |
---|---|---|
CFBundleDisplayName | String | 应用程序的显示名称 |
CFBundleIconFile | String | 包含应用程序图标的文件的名称 |
CFBundleIdentifier | String | 应用程序的包标识符 |
CFBundleSignature | String | 应用程序的创建者签名 |
CFBundleDocumentTypes | Array | 描述文档类型的字典数组 应用程序可以打开;请参阅文档类型 |
CFBundleURLTypes | Array | 描述URL类型的字典数组 应用程序可以打开;请参阅URL类型 |
LSRequiresCarbon | String | 应用程序必须在OS X中本地运行吗? |
LSPrefersCarbon | String | 应用程序是否更喜欢在OS X中本地运行? |
LSRequiresClassic | String | 应用程序必须在经典仿真环境中运行吗? |
LSPrefersClassic | String | 应用程序是否更喜欢在经典仿真环境中运行? |
LSBackgroundOnly | String | 应用程序是否仅在后台运行? |
LSUIElement | String | 应用程序是否是用户交互界面元素(也就是说,没有菜单栏,不应该出现在Dock或Force Quit窗口中)? |
CFBundleDisplayName
键指定应用程序的显示名称;此键可以通过将其包含在适当.lproj
子目录的InfoPlist.strings
文件中来本地化。
CFBundleIconFile
标识包含用于在屏幕上显示应用程序的图标图像的文件。
CFBundleIdentifier
定义应用程序的*包标识符,一个唯一的标识字符串,用于在运行时定位其包。
CFBundleSignature
是应用程序的创建者签名,*一个四个字符的代码,用于标识属于此应用程序的文档文件。
键LSRequiresCarbon
、LSPrefersCarbon
、LSRequiresClassic
、LSPrefersClassic
、LSBackgroundOnly
和LSUIElement
指定应用程序应该在其中运行的环境的各个方面。
对于这些键中的任何一个,字符串值“1”
声明相应的属性为true。
(在OS X 10.2或更高版本中,这些键也可以采用Boolean
或Number
类型的值,而不是String
,但早期系统版本不支持此类值。)
这些LSRequiresCarbon
是互斥LSPrefersCarbon
:最多可以将其中一个设置为"1"
。
LSPrefersClassic``LSRequiresClassic``flags
字段获取有关这四个键的值的信息LSCopyItemInfoForRef
和LSCopyItemInfoForURL
。
LSRequiresCarbon
指定应用程序必须在OS X中本地运行,并且不能在经典仿真环境中运行;LSRequiresClassic
表示相反。
LSPrefersCarbon
和LSPrefersClassic
表示应用程序可以在任一环境中运行,但对其中一个有偏好;Finder通过在应用程序的获取信息窗口中显示一个复选框来为用户提供使用哪个环境的选择,该复选框标有“在经典环境中打开”,最初根据应用程序本身指定的键选择或取消选择。
注意: 在名称LSRequiresCarbon
和LSPrefersCarbon
中使用单词Carbon
具有误导性,因为这些键实际上表示应用程序需要或更喜欢在MacOSX中本地运行,而不管它是否专门基于Carbon;特别是,LSRequiresCarbon
可以同样适用于Cocoa或Carbon应用程序。
还要注意捆绑信息属性列表中的LSRequiresCarbon
标志和项目信息记录中的kLSItemInfoIsNativeApp
标志之间的含义上的细微差异:前者表示应用程序必须本地运行并且不能在Classic环境中运行,而后者仅表示应用程序有能力本地运行。
设置kLSItemInfoIsNativeApp
的应用程序也可能能够在经典环境中运行,具体取决于kLSItemInfoPrefersNative
和kLSItemInfoPrefersClassic
标志的设置。
如果四个键都没有设置为"1"
,Launch Services会通过其他方式推断应用程序所需或首选环境:
- 如果应用程序是捆绑的,则假定它是本机Mac应用程序,并在本机运行(相当于
LSRequiresCarbon
)。 - 如果应用程序未捆绑,并且其资源fork包含
'plst'
或'carb'
资源,则假定它与任一环境兼容,但更喜欢本地运行(相当于LSPrefersCarbon
)。 - 如果应用程序没有捆绑,并且没有
'plst'
或'carb'
资源,则假定它是一个经典应用程序,不能在本地运行(相当于LSRequiresClassic
)。
对于Launch Services而言,最重要的属性列表键是CFBundleDocumentTypes
和CFBundleURLTypes
。
与每个键关联的值是字典数组(分别为类型-定义和方案-定义字典),每个字典声明(声明)应用程序准备处理的一系列文档文件或URL。
Launch Services使用此信息来决定使用哪个应用程序打开给定的文档文件或URL。
文档类型
类型定义字典定义了*文档类型,*即应用程序可以处理的一系列文档文件。
表1-2显示了该字典中的相关键。
(有关类型定义字典中这些键和其他键的更多详细信息,请参阅 运行时配置指南 。)
Table 1-2 Keys in a type-definition dictionary
钥匙 | 类型 | 描述 |
---|---|---|
CFBundleTypeName | String | 文档类型的抽象名称(也称为其类型字符串) |
CFBundleTypeIconFile | String | 用于显示此类型文档的图标文件的名称 |
CFBundleTypeOSTypes | Array | 属于此文档类型的文档的四字符文件类型数组 |
CFBundleTypeExtensions | Array | 属于此文档类型的文档的文件扩展名数组 |
CFBundleTypeMIMETypes | Array | 属于此文档类型的文档的MIME类型数组 |
CFBundleTypeRole | String | 应用程序声称对文件的作用 这种类型;请参阅应用程序角色 |
LSTypeIsPackage | Boolean | 指定文档是否作为捆绑包分发。 |
CFBundleTypeName
键指定文档类型的种类字符串,这是一个用户可见的描述,用于表征屏幕上的这种类型的文档(例如在Finder的获取信息窗口或Finder列表视图的Kind列中)。
可以通过将此键包含在相应.lproj
子目录的InfoPlist.strings
文件中来本地化此键。
CFBundleTypeIconFile
标识包含图标图像的文件,用于在屏幕上显示这种类型的文档。
LSTypeIsPackage
指定文档是打包包(true
)还是单个文件(false
)。
属于给定文档类型的文件可以通过其文件类型、文件扩展名或MIME类型来表征。
类型定义字典中的CFBundleTypeOSTypes
键指定表征该类型文档的四字符文件类型代码数组;同样,CFBundleTypeExtensions
指定文件扩展名数组和CFBundleTypeMIMETypes
MIME类型数组。
如果相应的文件特征不相关,可以省略这些单独的键中的任何一个,但必须至少存在其中一个才能使文件类型非空。
要允许应用程序在拖放操作期间接受不受限制的文件类型或扩展名的文件,您可以使用特殊的通配符值'****'
或'*'
分别用于CFBundleOSTypes
或CFBundleTypeExtensions
。
(这些仅在拖放操作中执行,而不是在用户通过双击打开文档时执行。)最后,CFBundleTypeRole
键指定应用程序对给定类型文档声明的角色,如应用程序角色下所述。
URL 类型
方案定义字典类似于类型定义字典,但定义的是URL类型(应用程序可以处理的一系列URL)而不是文档类型。
表1-3显示了这种类型字典中的键。
(有关这些键的更多详细信息,请参阅 运行时配置指南 。)
钥匙 | 类型 | 描述 |
---|---|---|
CFBundleURLName | String | URL类型的抽象名称(也称为其类型字符串) |
CFBundleURLIconFile | String | 用于显示此类型URL的图标文件的名称 |
CFBundleURLSchemes | Array | 属于此URL类型的URL的URL方案数组 |
CFBundleURLNameCFBundleURLName
键指定URL类型的种类字符串,这是一个用户可见的描述,用于表征屏幕上此类型的URL(例如在Finder的获取信息窗口或Finder列表视图的Kind列中)。
可以通过将此键包含在相应.lproj
子目录的InfoPlist.strings
文件中来本地化此键。
CFBundleURLIconFile
标识包含用于在屏幕上显示此类型URL的图标图像的文件。
属于给定URL类型的URL由其方案组件表征,例如http
、ftp
、mailto
或file
。
方案定义字典中的CFBundleURLSchemes
键指定表征该类型URL的方案数组。
应用角色
在声明文档类型时,应用程序可以声明该类型文档的特定角色,定义应用程序能够对此类文档执行的操作类型。
该角色通过应用程序类型定义字典中给定文档类型的CFBundleTypeRole
键声明。
Launch Services识别三个这样的角色:
Editor
应用程序可以读取、呈现、操作和保存给定类型的文档。Viewer
应用程序可以读取和呈现给定类型的文档,但不能操作或保存它们。None
应用程序不能对给定类型的文档进行操作。
此角色对于声明应用程序无法打开的文档类型的信息很有用,例如它们的抽象名称和图标文件。
Launch Services定义了一组表示各种可能角色的位掩码常量LSRolesMask
类型。
Launch Services函数查找文档或文档系列(LSGetApplicationForItem
、LSGetApplicationForURL
和LSGetApplicationForInfo
)的首选应用程序,或确定给定应用程序是否可以打开指定文档(LSCanRefAcceptItem
和LSCanURLAcceptURL
),采用此类型的参数来指定应用程序相对于文档的所需角色。
4、申请注册
用户系统上可用的所有应用程序都必须注册,以使启动服务知道它们,并将它们的文档绑定和其他信息复制到其数据库中。
通常不需要显式执行此任务,因为OS X系统软件中内置的各种实用程序和服务会自动处理此任务:
- 一个内置的后台工具,在系统启动或新用户登录时运行,自动搜索系统、网络、本地和用户域中的应用程序文件夹,并注册它在那里找到的任何新应用程序。
(此操作类似于早期版本Mac OS中的“重建桌面”。) - Finder会在发现所有应用程序时自动注册它们,例如当它们被拖到用户磁盘上或用户导航到包含它们的文件夹时。
- 当用户尝试打开在Launch Services数据库中找不到首选应用程序的文档时,Finder会显示一个对话框,要求用户选择用于打开文档的应用程序。
然后,它会在启动该应用程序之前注册该应用程序。
尽管有这些自动注册实用程序,但有时可能需要向Launch Services显式注册应用程序。
例如,尽管鼓励开发人员打包他们的应用程序,以便只需将它们拖到用户磁盘上即可安装,但某些应用程序可能需要更复杂的自定义安装程序软件。
在这种情况下,安装程序应调用Launch Services注册函数LSRegisterFSRef
或LSRegisterURL
之一来显式注册应用程序。
注册函数采用一个布尔参数inUpdate
,当正在注册的应用程序已经存在于Launch Services数据库中时,该参数控制函数的行为。
如果该参数true
,Launch Services会无条件地重新注册应用程序,替换数据库中可能已经存在的任何先前信息;如果该参数false
,则只有当应用程序当前修改时间比数据库中记录的时间更近时,才会重新注册该应用程序。
在对应用程序的启动服务相关信息进行任何重大更改后,您应该通过调用LSRegisterFSRef
或LSRegisterURL
并将inUpdate
设置为true
来显式重新注册应用程序,或者更新应用程序的修改时间以确保它将通过上述自动注册实用程序进行更新。
**注意:**您可以在终端窗口中使用BSDtouch
命令更新应用程序的修改时间。
例如,命令touch /Applications/TextEdit.app
将TextEdit的修改时间设置为当前时间。
5、开放式运营
Launch Services的主要目的是打开应用程序、文档和URL。
具体如何执行取决于要打开的项目类型,如以下部分所述。
Opening 应用
当要打开的项目是应用程序(或带有指定应用程序的方案file
的URL)时,Launch Services会检查应用程序是否已经在运行并相应地继续:
- 如果应用程序尚未运行,Launch Services将启动它(启动它)并向其发送
'oapp'
(“打开应用程序”)Apple事件。
应用程序应通过执行其正常启动处理来响应此事件。 - 如果应用程序已经在运行,Launch Services会激活它(将其带到屏幕前面)并向它发送一个
'rapp'
(“重新打开应用程序”)苹果事件。
这指示应用程序采取一些额外的行动,如有必要,向用户提供它已经激活的视觉反馈:例如,如果它没有其他窗口已经打开,它可能会打开一个空的文档窗口或文档创建对话框。
在任何一种情况下,Launch Services都会将应用程序添加到Apple菜单中的最近项目子菜单中。
Opening 文件
如果要打开的项目是文档(或带有指定文档文件的方案file
的URL),Launch Services必须首先确定要使用什么应用程序来打开该项目。
这被称为该项目的 首选应用程序。
如 用户指定绑定首选项下所述,OS X用户交互界面允许用户指定文档与其首选应用程序之间的显式绑定。
如果已经指定了这种显式绑定,则优先于任何其他考虑;如果不是,Launch Services使用一组隐式绑定标准来确定首选应用程序,如首选应用程序下所述。
一旦确定了首选应用程序,Launch Services就会启动或激活它(取决于它是否已经在运行),并向它发送一个'odoc'
(“打开文档”)Apple事件,指示它打开指定的文档。
(如果文档要打印而不仅仅是打开,则发送一个'pdoc'
(“打印文档”)Apple事件,而不是'odoc'
;在file
URL的情况下,如果应用程序声称使用该方案处理URL,则会发送一个‘GURL'
(“获取URL”)Apple事件。)
最后,Launch Services将应用程序和文档(或URL)添加到Apple菜单中的最近项目子菜单中。
打开URL
如果要打开的项目是具有file
以外方案的URL,则它的打开方式与文档基本相同,但有以下例外:
- 如首选应用程序中所述,用于选择首选应用程序的隐式绑定标准基于URL的方案组件,而不是创建者签名、文件类型或文件扩展名。
- 启动或激活应用程序后发送到应用程序的Apple事件是
'GURL'
(“获取URL”)而不是'odoc'
(“打开文档”)。
启动或激活首选应用程序后,Launch Services会将应用程序添加到Apple菜单中的最近项目子菜单中。
启动选项
打开应用程序时(无论是单独打开还是打开一个或多个文档或URL),您可以指定各种启动选项来控制启动或激活它的方式。
这些可以包括:
- 是否在专门指定的应用程序或他们自己的首选应用程序中打开文档或URL(如果有)
- 是打印文档或URL(如果有)还是仅打开它们
- 是将应用程序和文档(如果有)添加到Finder的最近项目菜单还是禁止此操作
- 是允许应用程序在后台打开还是在仅后台应用程序时失败
- 是否打开应用程序而不将其带到前台
- 是否允许应用程序在Classic仿真环境中打开,或者如果它是仅限Classic的应用程序则失败
- 是否启动应用程序的新实例,即使另一个实例已经在运行
- 启动后是否隐藏应用程序
- 启动此应用程序后是否隐藏所有其他应用程序
- 是同步启动应用程序还是异步启动应用程序(见下一节)
同步和异步启动
启动应用程序时可以指定的选项之一是同步启动还是异步启动:
- 在同步启动中,控制不会从启动应用程序的Launch Services函数返回,直到应用程序完成其启动序列(当应用程序的图标停止在Dock中弹跳时向用户直观地指示)。
- 在异步启动时,控件会立即返回,而Dock中的图标仍在“弹跳”。
启动序列完成后,您的应用程序会收到一个Carbon类型的事件通知kEventAppLaunchNotification
。
您可以安装一个事件处理程序回调例程,以适当的方式响应此事件。
在调用启动应用程序的Launch Services函数时,您可以提供一个任意的4字节引用常量,该常量将作为通知事件的一部分传回给您的处理程序例程。
6、用户指定的绑定首选项
Launch Services在确定文件或非文件URL的首选应用程序时的首要优先级是用户是否为该项目指定了显式绑定首选项。
选择文件的绑定偏好设置
用户可以通过选择Finder中的项目并选择Get Info命令来指定文件的首选应用程序(参见图1-1)。
图1-1选择获取信息
Get Info窗口的打开方式窗格包含一个弹出菜单,其中列出了Launch Services数据库中声称接受所选项目的所有已知应用程序(参见图1-2)。
然后,用户可以从菜单中选择一个应用程序成为该项目的首选应用程序(图1-3)。
注意:单个项目的显式绑定首选项不是用户特定的,而是系统范围的——也就是说,即使不同的用户登录,它们也会继续应用于同一台计算机上的给定项目。
图1-2获取信息窗口
图1-3选择项目的首选应用程序
单击全部更改按钮(图1-4)使所选应用程序成为同一文档或URL类型的所有项目的首选应用程序,而不仅仅是所选的单个项目。
图1-4选择项目类型的首选应用程序
有时,用户可能希望指定一个不声称接受给定文档或URL的首选应用程序。
(例如,这可能有助于在文本编辑器中将文本编码格式(如超文本标记语言)的文档打开为未编码文本。)打开方式窗格弹出菜单中的其他项打开图1-5所示的对话框,用户可以在其中导航到所需的应用程序。
弹出菜单中标记为对话框顶部显示的所有应用程序项允许选择任何所需的应用程序;推荐的应用程序会使那些不声称接受该项目的应用程序变暗。
图1-5 选择其他应用程序对话框
为URL选择绑定首选项
没有用于设置非文件URL方案处理程序的系统级用户交互界面。
但是,单个应用程序可以允许用户为特定URL方案选择首选应用程序。
例如:
- Safari应用程序允许用户通过选择默认Web浏览器来设置
http:
handler。 - Mail应用程序允许用户通过选择默认电子邮件阅读器来设置
mailto:
handler。
7、首选应用
Launch Services在需要时执行文档绑定操作:
- 计算用于文档的最佳图标。
- 计算文档的类型字符串,如Finder列表视图和其他一些上下文中所示。
- 打开一个文档。
Launch Services 使用一系列按优先级排序的绑定标准来确定打开给定文档或URL的首选应用程序。
这些标准由打开文档文件(LSOpenFSRef
、LSOpenFromRefSpec
)或URL(LSOpenCFURLRef
、LSOpenFromURLSpec
)的Launch Services函数使用,也由那些仅定位此类项目的首选应用程序而未实际打开它的函数(LSGetApplicationForItem
、LSGetApplicationForURL
)使用。
它们也由LSGetApplicationForInfo
函数使用,该函数定位用于打开由指定标识特征定义的一系列项目的首选应用程序。
首选文件申请
对于单个文档文件(无论是由文件系统引用还是带有方案file
的URL指定),标准如下:
- 如果用户为文档(或其所属的整个文档类型)指定了显式绑定,则首选应用程序是用户指定的应用程序。
- 如果文档具有文件扩展名(或者如果已将其指定为
LSGetApplicationForInfo
的参数),请在Launch Services数据库中查找声称接受具有该扩展名的文档的所有应用程序。 - 如果文档带有四个字符的文件类型(或者如果已将其指定为参数),请找到所有声称接受该类型文件的应用程序。
- 如果由于步骤2-3而发现不止一项申请,则按所示顺序应用以下标准:
- 如果文档带有四个字符的创建者签名(或者如果已将其指定为参数),则优先考虑声称接受具有该签名的文档的任何应用程序(通常是签名所属的应用程序)。
- 优先考虑本机OS X应用程序,而不是在经典仿真环境中运行的应用程序。
- 优先考虑驻留在引导卷上的应用程序,而不是驻留在其他文件系统卷上的应用程序。
- 优先考虑驻留在本地卷上的应用程序,而不是驻留在远程卷上的应用程序。
- 如果发现同一应用程序的两个或多个版本,则优先选择具有由
CFBundleVersion
标识的最新版本号的版本。
如果在应用所有上述标准后仍有两个或多个候选应用程序,Launch Services会以未指定的方式选择剩余应用程序之一。
注意:标准4a不适用于OS X 10.6及更高版本。
标准4c和4d不适用于OS X 10.2及更早版本。
Apple保留在未来系统版本中更改选择标准的权利。
注意:当要打开的项目是文件系统文件夹时,它被视为首选应用程序是Finder的文档文件。
这提供了一种方便的方式来要求Finder打开一个显示指定文件夹内容的窗口。
URL的首选应用程序
具有file
以外方案的URL的条件与文档文件的条件相似,只是搜索基于URL的方案,而不是基于文件特征,如创建者签名、文件扩展名和文件类型:
- 如果用户为URL(或其所属的整个URL类型)指定了显式绑定,则首选应用程序是用户指定的应用程序。
- 如果未指定显式绑定,请在Launch Services数据库中找到声称接受具有给定方案的URL的所有应用程序。
- 如果在步骤2中找到多个应用程序,请按所示顺序应用以下标准:
- 优先考虑本机OS X应用程序,而不是在经典仿真环境中运行的应用程序。
- 优先考虑驻留在引导卷上的应用程序,而不是驻留在其他文件系统卷上的应用程序。
- 优先考虑驻留在本地卷上的应用程序,而不是驻留在远程卷上的应用程序。
- 如果发现同一应用程序的两个或多个版本,请优先选择具有最新版本号的版本。
如果在应用所有上述标准后仍有两个或多个候选应用程序,Launch Services会以未指定的方式选择剩余应用程序之一。
注意:标准3b和3c不适用于OS X 10.2及更早版本。
Apple保留在未来系统版本中更改选择标准的权利。
三、启动服务任务
本章总结了如何使用启动服务在应用程序中执行常见任务。
1、开幕项目
您希望使用启动服务执行的最常见操作是打开应用程序、文档文件和URL。
根据具体情况,您可以为此使用四个启动服务函数中的任何一个:LSOpenFSRef
、LSOpenFromRefSpec
、LSOpenCFURLRef
或LSOpenFromURLSpec
。
按文件系统参考打开项目
当您希望打开的项目由文件系统引用(FSRef
)标识时,打开它的最简单方法是使用LSOpenFSRef
。
您只需提供文件系统引用,Launch Services就会以简单明了的默认方式打开该项目:
- 如果指定项目是应用程序:
- 如果应用程序尚未运行,则启动并发送
'oapp'
(“打开应用程序”)Apple事件。 - 如果应用程序已经在运行,则激活(带到屏幕前面)并发送
'rapp'
(“重新打开应用程序”)Apple事件。
- 如果应用程序尚未运行,则启动并发送
- 如果指定项目是文档,则启动其首选应用程序(或激活它,如果它已经在运行)并发送
'odoc'
(打开文档)Apple事件,指示其打开文档。
LSOpenFSRef
反过来调用更通用的函数LSOpenFromRefSpec
,这是一个“瑞士军刀”函数,提供对打开应用程序和文档的全部选项的访问。
如果您需要请求默认行为以外的东西,您可以自己直接调用此函数。
例如,您可以使用它来:
- 在相同或不同的应用程序中一次打开多个文档
- 强制文档在其首选应用程序以外的应用程序中打开
- 打开文档进行打印,而不是简单地查看或编辑
- 强制应用程序在经典仿真环境中打开
- 打开指定的应用程序并隐藏所有其他应用程序
- 防止将应用程序或文档添加到Finder的最近项目菜单中
不是对要打开的项目的直接文件系统引用,而是提供指向*启动规范、*标识一个或多个项目的LSLaunchFSRefSpec
类型的数据结构以及有关如何打开它们的附加信息的指针:
- 要打开一个或多个文档,请在启动规范的
itemRefs
字段中传递一个文件系统引用数组;numDocs
字段告诉有多少个。
如果appRef
字段也是非空的,它指定在其中打开文档的应用程序;否则,每个文档将在其自己的首选应用程序中打开。 - 要在不指定任何文档的情况下打开应用程序,请在启动规范的
appRef
字段中传递对应用程序的文件系统引用,并将itemRefs
字段设置为NULL
,将numDocs
设置为0
。
启动规范中的附加信息包括:
- 包含各种启动选项的标志字(
launchFlags
),用于控制打开应用程序的方式;请参阅启动选项 - 指向可选Apple事件描述符记录(
passThruParams
)的指针,其中包含要与应用程序在打开时接收到的Apple事件一起传递的参数信息 - 一个可选的引用常量(
asyncRefCon
),要传递给异步启动通知的Carbon事件处理程序例程,如同步和异步启动
对于LSOpenFSRef
和LSOpenFromRefSpec
,输出参数outLaunchedRef
包含一个指向文件系统引用的指针,函数将设置该指针以指示打开的应用程序(或第一个此类应用程序,如果在不同应用程序中打开了多个文档)。
如果对此信息不感兴趣,您可以将此参数设置为NULL
。
按URL打开项目
要打开URL,您可以使用Launch Services函数LSOpenCFURLRef
或LSOpenFromURLSpec
。
它们类似于LSOpenFSRef
和LSOpenFromRefSpec
,但接受Core Foundation URL引用(CFURLRef
)而不是文件系统引用。
当您有要打开的应用程序或文档的文件系统路径名时,这些函数通常也很有用:您可以使用方案file
构建包含路径的URL,然后使用此URL代替文件系统引用来打开项目。
LSOpenCFURLRef
和LSOpenFromURLSpec
函数是使用其他方案打开URL的唯一方法,例如http
、ftp
或mailto
。
与文件系统引用的LSOpenFSRef
一样,LSOpenCFURLRef
以默认方式在其首选应用程序中打开指定的URL。
更通用的函数LSOpenFromURLSpec
接受启动规范(类似于LSOpenFromRefSpec
的规范,但类型为LSLaunchURLSpec
而不是LSLaunchFSRefSpec
),更详细地指定打开URL的方式。
与LSOpenFromRefSpec
一样,如果您需要请求LSOpenCFURLRef
提供的默认行为以外的内容,您可以自己直接调用此函数。
同时LSOpenCFURLRef
和LSOpenFromURLSpec
确定使用哪个应用程序打开指定的URL,启动应用程序(或激活它,如果它已经在运行),并向它发送一个Apple事件,指示它打开URL。
(使用LSOpenFromURLSpec
,您可以通过在启动规范的appURL
字段中显式指定另一个应用程序来覆盖URL的首选应用程序。)通常,应用程序会收到一个'GURL'
(“获取URL”)Apple事件;但是如果URL的方案是file
并且应用程序没有声称接受此方案的URL,则会发送一个'odoc'
(“打开文档”)Apple事件。
与文件系统引用的对应函数一样,这两个基于URL的函数都可以选择返回实际打开了哪个应用程序的信息(或者第一个,如果在不同的应用程序中打开了多个URL)。
此信息通过Core Foundation URL引用传回,您可以在输出参数outLaunchedURL
中提供指向该引用的指针。
如果对应用程序的身份不感兴趣,您可以将此参数设置为NULL
。
2、查找项目的首选应用
若要查找文档文件、URL或MIME类型的首选应用程序而不打开它,请分别使用Launch Services函数LSGetApplicationForItem
、LSGetApplicationForURL
或LSCopyApplicationForMIMEType
。
您可以使用文档的文件系统引用(FSRef
)、URL的Core Foundation URL引用(CFURLRef
)或指定MIME类型的字符串的Core Foundation字符串引用(CFStringRef
)来标识感兴趣的项目。
另一个Launch Services函数LSGetApplicationForInfo
查找由文件类型、创建者签名、文件扩展名或这些特征的任意组合定义的文档系列的首选应用程序。
在每种情况下,您都必须提供一个角色掩码(LSRolesMask
),指定应用程序应针对给定项目或项目系列声明的一个或多个角色(Editor
、Viewer
或None
)。
(请注意,None
并不意味着“根本没有角色”,而是指应用程序可以针对该项目声明的特定角色:提供标识信息,如显示名称和图标文件,而实际上无法打开项目本身。)如果您不关心应用程序声明什么角色,请使用掩码值kLSRolesAll
。
要接收结果,您需要传递一个指向文件系统引用的指针(在outAppRef
参数中)、一个Core Foundation URL引用(在outAppURL
参数中),或两者兼而有之;Launch Services将设置指定的数据结构以引用项目的首选应用程序。
如果您不想接收该形式的结果,您可以为这些参数中的任何一个传递一个空指针,但两个指针中至少有一个必须为非空。
(在LSCopyApplicationForMIMEType
的情况下,只有URL选项可用;没有outAppRef
参数。)
要查找可以打开具有指定角色的给定项的所有已知应用程序,请使用Launch Services函数LSCopyApplicationURLsForURL
。
尽管此函数只能接受URL引用而不能接受文件系统引用,但您也可以将其用于文档文件,方法是通过传递带有引用所需文档的方案文件的URLfile
。
Launch Services函数LSFindApplicationForInfo
根据应用程序的名称、创建者签名、捆绑ID或这些特征的任意组合来定位应用程序。
(请注意,这与LSGetApplicationForInfo
的不同之处在于,指定的特征适用于应用程序本身,而不是它可以打开的文档文件。)与前面讨论的其他Launch Services函数一样,您可以通过传递指向要填充信息的适当数据结构的指针来接收文件系统引用、URL或两者兼而有之的结果。
3、测试应用程序是否可以打开项目
通常,找出给定的应用程序是否声称能够打开特定的文档或URL是很有用的。
Launch Services函数LSCanRefAcceptItem
和LSCanURLAcceptURL
提供了这些信息。
您可以提供对项目和目标应用程序的文件系统引用或URL引用,以及角色掩码和控制函数行为某些技术方面的标志字;函数通过设置一个布尔变量来响应,您可以向该变量提供一个指针,以指示应用程序是否可以接受指定的项目。
4、注册应用程序
通常不需要向Launch Services显式注册应用程序,因为每当Finder知道应用程序、系统启动或新用户登录时,都会自动为您注册(请参阅应用程序注册)。
在极少数情况下,当您确实需要显式注册应用程序时(例如在自定义安装程序中),您可以使用Launch Services功能LSRegisterFSRef
或LSRegisterURL
,这取决于应用程序是用文件系统引用还是Core Foundation URL引用标识的。
在任何一种情况下,应用程序及其文档绑定信息都会复制到Launch Services数据库中,从而使应用程序可用于打开文档和URL。
5、获取有关项目的信息
您可以使用Launch Services函数LSCopyItemInfoForRef
和LSCopyItemInfoForURL
来获取有关文件系统对象(如应用程序、文档、文件夹或卷)的各种信息。
您可以提供文件系统引用或Core Foundation URL引用(带有方案file
)来标识感兴趣的项目,以及指定所需信息的标志字(LSRequestedInfo
)和指向项目信息记录(LSItemInfoRecord
)的指针,以便在其中接收回信息。
此记录中的信息可以包括项目的文件类型、创建者签名、文件扩展名和描述项目属性的各种标志(参见项目信息)。
您可能会发现关于项目的其他两条有用的信息是它的显示名称(用于在屏幕上向用户显示它的名称)和它的种类字符串(例如在Finder的获取信息窗口或Finder列表视图的Kind列中使用,以表征项目的一般性质,例如Application
、Folder
、Alias
、JPEG Picture
、QuickTime Movie
或FrameMaker Document
)。
您可以使用Launch Services函数获取显示名称LSCopyDisplayNameForRef
或LSCopyDisplayNameForURL
以及带有LSCopyKindStringForRef
、LSCopyKindStringForURL
、LSCopyKindStringForTypeInfo
或LSCopyKindStringForMIMEType
的种类字符串。
2024-06-16(日)