Apple - Launch Services Programming Guide

本文翻译整理自: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引用:例如,可以使用LSGetApplicationForItemLSGetApplicationForURL函数找到打开项目的首选应用程序。

此外,某些启动服务功能不适用于特定的单个项目,而是适用于由某些识别特征定义的项目系列。
这些特征可以包括:

  • 四个字符的文件类型代码
  • 四个字符的创建者签名
  • 文件扩展名
  • MIME(多用途Internet邮件扩展)类型

例如,Launch Services函数LSGetApplicationForInfo查找由文件类型、创建者签名、文件扩展名或这些特征的任意组合定义的文档系列的首选应用程序;LSCopyApplicationForMIMEType函数查找具有指定MIME类型的项目的首选应用程序。

注意: 在OS X 10.6及更高版本中,Launch Services在将文档绑定到应用程序时不再考虑文件创建者签名。
当创建者签名附加到文档时,Launch Services会忽略它。
此外,函数LSCopyKindStringForTypeInfoLSGetApplicationForInfo忽略包含创建者签名的参数。


2、项目信息

某些Launch Services函数返回有关项目或项目系列的请求信息。
这可以包括:

  • 项目的文件类型
  • 项目的创建者签名
  • 项目的文件扩展名
  • 项目的显示名称:用于向用户显示其名称的字符串(例如在Finder或Dock中)
  • 项目的*种类字符串:*用于描述其一般性质的字符串(例如,在Finder的获取信息窗口或Finder列表视图的种类列中),例如ApplicationFolderAliasJPEG PictureQuickTime MovieFrameMaker 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

钥匙类型描述
CFBundleDisplayNameString应用程序的显示名称
CFBundleIconFileString包含应用程序图标的文件的名称
CFBundleIdentifierString应用程序的包标识符
CFBundleSignatureString应用程序的创建者签名
CFBundleDocumentTypesArray描述文档类型的字典数组 应用程序可以打开;请参阅文档类型
CFBundleURLTypesArray描述URL类型的字典数组 应用程序可以打开;请参阅URL类型
LSRequiresCarbonString应用程序必须在OS X中本地运行吗?
LSPrefersCarbonString应用程序是否更喜欢在OS X中本地运行?
LSRequiresClassicString应用程序必须在经典仿真环境中运行吗?
LSPrefersClassicString应用程序是否更喜欢在经典仿真环境中运行?
LSBackgroundOnlyString应用程序是否仅在后台运行?
LSUIElementString应用程序是否是用户交互界面元素(也就是说,没有菜单栏,不应该出现在Dock或Force Quit窗口中)?

CFBundleDisplayName键指定应用程序的显示名称;此键可以通过将其包含在适当.lproj子目录的InfoPlist.strings文件中来本地化。
CFBundleIconFile标识包含用于在屏幕上显示应用程序的图标图像的文件。
CFBundleIdentifier定义应用程序的*包标识符,一个唯一的标识字符串,用于在运行时定位其包。
CFBundleSignature是应用程序的
创建者签名,*一个四个字符的代码,用于标识属于此应用程序的文档文件。

LSRequiresCarbonLSPrefersCarbonLSRequiresClassicLSPrefersClassicLSBackgroundOnlyLSUIElement指定应用程序应该在其中运行的环境的各个方面。
对于这些键中的任何一个,字符串值“1”声明相应的属性为true。
(在OS X 10.2或更高版本中,这些键也可以采用BooleanNumber类型的值,而不是String,但早期系统版本不支持此类值。)

这些LSRequiresCarbon是互斥LSPrefersCarbon:最多可以将其中一个设置为"1"
LSPrefersClassic``LSRequiresClassic``flags字段获取有关这四个键的值的信息LSCopyItemInfoForRefLSCopyItemInfoForURL
LSRequiresCarbon指定应用程序必须在OS X中本地运行,并且不能在经典仿真环境中运行;LSRequiresClassic表示相反。
LSPrefersCarbonLSPrefersClassic表示应用程序可以在任一环境中运行,但对其中一个有偏好;Finder通过在应用程序的获取信息窗口中显示一个复选框来为用户提供使用哪个环境的选择,该复选框标有“在经典环境中打开”,最初根据应用程序本身指定的键选择或取消选择。


注意: 在名称LSRequiresCarbonLSPrefersCarbon中使用单词Carbon具有误导性,因为这些键实际上表示应用程序需要或更喜欢在MacOSX中本地运行,而不管它是否专门基于Carbon;特别是,LSRequiresCarbon可以同样适用于Cocoa或Carbon应用程序。
还要注意捆绑信息属性列表中的LSRequiresCarbon标志和项目信息记录中的kLSItemInfoIsNativeApp标志之间的含义上的细微差异:前者表示应用程序必须本地运行并且不能在Classic环境中运行,而后者仅表示应用程序有能力本地运行。
设置kLSItemInfoIsNativeApp的应用程序也可能能够在经典环境中运行,具体取决于kLSItemInfoPrefersNativekLSItemInfoPrefersClassic标志的设置。


如果四个键都没有设置为"1",Launch Services会通过其他方式推断应用程序所需或首选环境:

  • 如果应用程序是捆绑的,则假定它是本机Mac应用程序,并在本机运行(相当于LSRequiresCarbon)。
  • 如果应用程序未捆绑,并且其资源fork包含'plst''carb'资源,则假定它与任一环境兼容,但更喜欢本地运行(相当于LSPrefersCarbon)。
  • 如果应用程序没有捆绑,并且没有'plst''carb'资源,则假定它是一个经典应用程序,不能在本地运行(相当于LSRequiresClassic)。

对于Launch Services而言,最重要的属性列表键是CFBundleDocumentTypesCFBundleURLTypes
与每个键关联的值是字典数组(分别为类型-定义方案-定义字典),每个字典声明(声明)应用程序准备处理的一系列文档文件或URL。
Launch Services使用此信息来决定使用哪个应用程序打开给定的文档文件或URL。


文档类型

类型定义字典定义了*文档类型,*即应用程序可以处理的一系列文档文件。
表1-2显示了该字典中的相关键。
(有关类型定义字典中这些键和其他键的更多详细信息,请参阅 运行时配置指南 。)


Table 1-2 Keys in a type-definition dictionary

钥匙类型描述
CFBundleTypeNameString文档类型的抽象名称(也称为其类型字符串)
CFBundleTypeIconFileString用于显示此类型文档的图标文件的名称
CFBundleTypeOSTypesArray属于此文档类型的文档的四字符文件类型数组
CFBundleTypeExtensionsArray属于此文档类型的文档的文件扩展名数组
CFBundleTypeMIMETypesArray属于此文档类型的文档的MIME类型数组
CFBundleTypeRoleString应用程序声称对文件的作用 这种类型;请参阅应用程序角色
LSTypeIsPackageBoolean指定文档是否作为捆绑包分发。

CFBundleTypeName键指定文档类型的种类字符串,这是一个用户可见的描述,用于表征屏幕上的这种类型的文档(例如在Finder的获取信息窗口或Finder列表视图的Kind列中)。
可以通过将此键包含在相应.lproj子目录的InfoPlist.strings文件中来本地化此键。
CFBundleTypeIconFile标识包含图标图像的文件,用于在屏幕上显示这种类型的文档。
LSTypeIsPackage指定文档是打包包(true)还是单个文件(false)。

属于给定文档类型的文件可以通过其文件类型、文件扩展名或MIME类型来表征。
类型定义字典中的CFBundleTypeOSTypes键指定表征该类型文档的四字符文件类型代码数组;同样,CFBundleTypeExtensions指定文件扩展名数组和CFBundleTypeMIMETypesMIME类型数组。
如果相应的文件特征不相关,可以省略这些单独的键中的任何一个,但必须至少存在其中一个才能使文件类型非空。
要允许应用程序在拖放操作期间接受不受限制的文件类型或扩展名的文件,您可以使用特殊的通配符值'****''*'分别用于CFBundleOSTypesCFBundleTypeExtensions
(这些仅在拖放操作中执行,而不是在用户通过双击打开文档时执行。)最后,CFBundleTypeRole键指定应用程序对给定类型文档声明的角色,如应用程序角色下所述。


URL 类型

方案定义字典类似于类型定义字典,但定义的是URL类型(应用程序可以处理的一系列URL)而不是文档类型。
表1-3显示了这种类型字典中的键。
(有关这些键的更多详细信息,请参阅 运行时配置指南 。)

钥匙类型描述
CFBundleURLNameStringURL类型的抽象名称(也称为其类型字符串)
CFBundleURLIconFileString用于显示此类型URL的图标文件的名称
CFBundleURLSchemesArray属于此URL类型的URL的URL方案数组

CFBundleURLNameCFBundleURLName键指定URL类型的种类字符串,这是一个用户可见的描述,用于表征屏幕上此类型的URL(例如在Finder的获取信息窗口或Finder列表视图的Kind列中)。
可以通过将此键包含在相应.lproj子目录的InfoPlist.strings文件中来本地化此键。
CFBundleURLIconFile标识包含用于在屏幕上显示此类型URL的图标图像的文件。

属于给定URL类型的URL由其方案组件表征,例如httpftpmailtofile
方案定义字典中的CFBundleURLSchemes键指定表征该类型URL的方案数组。


应用角色

在声明文档类型时,应用程序可以声明该类型文档的特定角色,定义应用程序能够对此类文档执行的操作类型。
该角色通过应用程序类型定义字典中给定文档类型的CFBundleTypeRole键声明。
Launch Services识别三个这样的角色:

  • Editor
    应用程序可以读取、呈现、操作和保存给定类型的文档。
  • Viewer
    应用程序可以读取和呈现给定类型的文档,但不能操作或保存它们。
  • None
    应用程序不能对给定类型的文档进行操作。
    此角色对于声明应用程序无法打开的文档类型的信息很有用,例如它们的抽象名称和图标文件。

Launch Services定义了一组表示各种可能角色的位掩码常量LSRolesMask类型。
Launch Services函数查找文档或文档系列(LSGetApplicationForItemLSGetApplicationForURLLSGetApplicationForInfo)的首选应用程序,或确定给定应用程序是否可以打开指定文档(LSCanRefAcceptItemLSCanURLAcceptURL),采用此类型的参数来指定应用程序相对于文档的所需角色。


4、申请注册

用户系统上可用的所有应用程序都必须注册,以使启动服务知道它们,并将它们的文档绑定和其他信息复制到其数据库中。
通常不需要显式执行此任务,因为OS X系统软件中内置的各种实用程序和服务会自动处理此任务:

  • 一个内置的后台工具,在系统启动或新用户登录时运行,自动搜索系统、网络、本地和用户域中的应用程序文件夹,并注册它在那里找到的任何新应用程序。
    (此操作类似于早期版本Mac OS中的“重建桌面”。)
  • Finder会在发现所有应用程序时自动注册它们,例如当它们被拖到用户磁盘上或用户导航到包含它们的文件夹时。
  • 当用户尝试打开在Launch Services数据库中找不到首选应用程序的文档时,Finder会显示一个对话框,要求用户选择用于打开文档的应用程序。
    然后,它会在启动该应用程序之前注册该应用程序。

尽管有这些自动注册实用程序,但有时可能需要向Launch Services显式注册应用程序。
例如,尽管鼓励开发人员打包他们的应用程序,以便只需将它们拖到用户磁盘上即可安装,但某些应用程序可能需要更复杂的自定义安装程序软件。
在这种情况下,安装程序应调用Launch Services注册函数LSRegisterFSRefLSRegisterURL之一来显式注册应用程序。

注册函数采用一个布尔参数inUpdate,当正在注册的应用程序已经存在于Launch Services数据库中时,该参数控制函数的行为。
如果该参数true,Launch Services会无条件地重新注册应用程序,替换数据库中可能已经存在的任何先前信息;如果该参数false,则只有当应用程序当前修改时间比数据库中记录的时间更近时,才会重新注册该应用程序。

在对应用程序的启动服务相关信息进行任何重大更改后,您应该通过调用LSRegisterFSRefLSRegisterURL并将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';在fileURL的情况下,如果应用程序声称使用该方案处理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的首选应用程序。
这些标准由打开文档文件(LSOpenFSRefLSOpenFromRefSpec)或URL(LSOpenCFURLRefLSOpenFromURLSpec)的Launch Services函数使用,也由那些仅定位此类项目的首选应用程序而未实际打开它的函数(LSGetApplicationForItemLSGetApplicationForURL)使用。
它们也由LSGetApplicationForInfo函数使用,该函数定位用于打开由指定标识特征定义的一系列项目的首选应用程序。


首选文件申请

对于单个文档文件(无论是由文件系统引用还是带有方案file的URL指定),标准如下:

  1. 如果用户为文档(或其所属的整个文档类型)指定了显式绑定,则首选应用程序是用户指定的应用程序。
  2. 如果文档具有文件扩展名(或者如果已将其指定为LSGetApplicationForInfo的参数),请在Launch Services数据库中查找声称接受具有该扩展名的文档的所有应用程序。
  3. 如果文档带有四个字符的文件类型(或者如果已将其指定为参数),请找到所有声称接受该类型文件的应用程序。
  4. 如果由于步骤2-3而发现不止一项申请,则按所示顺序应用以下标准:
    1. 如果文档带有四个字符的创建者签名(或者如果已将其指定为参数),则优先考虑声称接受具有该签名的文档的任何应用程序(通常是签名所属的应用程序)。
    2. 优先考虑本机OS X应用程序,而不是在经典仿真环境中运行的应用程序。
    3. 优先考虑驻留在引导卷上的应用程序,而不是驻留在其他文件系统卷上的应用程序。
    4. 优先考虑驻留在本地卷上的应用程序,而不是驻留在远程卷上的应用程序。
    5. 如果发现同一应用程序的两个或多个版本,则优先选择具有由CFBundleVersion标识的最新版本号的版本。

如果在应用所有上述标准后仍有两个或多个候选应用程序,Launch Services会以未指定的方式选择剩余应用程序之一。

注意:标准4a不适用于OS X 10.6及更高版本。
标准4c和4d不适用于OS X 10.2及更早版本。
Apple保留在未来系统版本中更改选择标准的权利。

注意:当要打开的项目是文件系统文件夹时,它被视为首选应用程序是Finder的文档文件。
这提供了一种方便的方式来要求Finder打开一个显示指定文件夹内容的窗口。


URL的首选应用程序

具有file以外方案的URL的条件与文档文件的条件相似,只是搜索基于URL的方案,而不是基于文件特征,如创建者签名、文件扩展名和文件类型:

  1. 如果用户为URL(或其所属的整个URL类型)指定了显式绑定,则首选应用程序是用户指定的应用程序。
  2. 如果未指定显式绑定,请在Launch Services数据库中找到声称接受具有给定方案的URL的所有应用程序。
  3. 如果在步骤2中找到多个应用程序,请按所示顺序应用以下标准:
    1. 优先考虑本机OS X应用程序,而不是在经典仿真环境中运行的应用程序。
    2. 优先考虑驻留在引导卷上的应用程序,而不是驻留在其他文件系统卷上的应用程序。
    3. 优先考虑驻留在本地卷上的应用程序,而不是驻留在远程卷上的应用程序。
    4. 如果发现同一应用程序的两个或多个版本,请优先选择具有最新版本号的版本。

如果在应用所有上述标准后仍有两个或多个候选应用程序,Launch Services会以未指定的方式选择剩余应用程序之一。

注意:标准3b和3c不适用于OS X 10.2及更早版本。
Apple保留在未来系统版本中更改选择标准的权利。


三、启动服务任务

本章总结了如何使用启动服务在应用程序中执行常见任务。


1、开幕项目

您希望使用启动服务执行的最常见操作是打开应用程序、文档文件和URL。
根据具体情况,您可以为此使用四个启动服务函数中的任何一个:LSOpenFSRefLSOpenFromRefSpecLSOpenCFURLRefLSOpenFromURLSpec


按文件系统参考打开项目

当您希望打开的项目由文件系统引用(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事件处理程序例程,如同步和异步启动

对于LSOpenFSRefLSOpenFromRefSpec,输出参数outLaunchedRef包含一个指向文件系统引用的指针,函数将设置该指针以指示打开的应用程序(或第一个此类应用程序,如果在不同应用程序中打开了多个文档)。
如果对此信息不感兴趣,您可以将此参数设置为NULL


按URL打开项目

要打开URL,您可以使用Launch Services函数LSOpenCFURLRefLSOpenFromURLSpec
它们类似于LSOpenFSRefLSOpenFromRefSpec,但接受Core Foundation URL引用(CFURLRef)而不是文件系统引用。
当您有要打开的应用程序或文档的文件系统路径名时,这些函数通常也很有用:您可以使用方案file构建包含路径的URL,然后使用此URL代替文件系统引用来打开项目。
LSOpenCFURLRefLSOpenFromURLSpec函数是使用其他方案打开URL的唯一方法,例如httpftpmailto

与文件系统引用的LSOpenFSRef一样,LSOpenCFURLRef以默认方式在其首选应用程序中打开指定的URL。
更通用的函数LSOpenFromURLSpec接受启动规范(类似于LSOpenFromRefSpec的规范,但类型为LSLaunchURLSpec而不是LSLaunchFSRefSpec),更详细地指定打开URL的方式。
LSOpenFromRefSpec一样,如果您需要请求LSOpenCFURLRef提供的默认行为以外的内容,您可以自己直接调用此函数。

同时LSOpenCFURLRefLSOpenFromURLSpec确定使用哪个应用程序打开指定的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函数LSGetApplicationForItemLSGetApplicationForURLLSCopyApplicationForMIMEType
您可以使用文档的文件系统引用(FSRef)、URL的Core Foundation URL引用(CFURLRef)或指定MIME类型的字符串的Core Foundation字符串引用(CFStringRef)来标识感兴趣的项目。
另一个Launch Services函数LSGetApplicationForInfo查找由文件类型、创建者签名、文件扩展名或这些特征的任意组合定义的文档系列的首选应用程序。

在每种情况下,您都必须提供一个角色掩码LSRolesMask),指定应用程序应针对给定项目或项目系列声明的一个或多个角色(EditorViewerNone)。
(请注意,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函数LSCanRefAcceptItemLSCanURLAcceptURL提供了这些信息。
您可以提供对项目和目标应用程序的文件系统引用或URL引用,以及角色掩码和控制函数行为某些技术方面的标志字;函数通过设置一个布尔变量来响应,您可以向该变量提供一个指针,以指示应用程序是否可以接受指定的项目。


4、注册应用程序

通常不需要向Launch Services显式注册应用程序,因为每当Finder知道应用程序、系统启动或新用户登录时,都会自动为您注册(请参阅应用程序注册)。
在极少数情况下,当您确实需要显式注册应用程序时(例如在自定义安装程序中),您可以使用Launch Services功能LSRegisterFSRefLSRegisterURL,这取决于应用程序是用文件系统引用还是Core Foundation URL引用标识的。
在任何一种情况下,应用程序及其文档绑定信息都会复制到Launch Services数据库中,从而使应用程序可用于打开文档和URL。


5、获取有关项目的信息

您可以使用Launch Services函数LSCopyItemInfoForRefLSCopyItemInfoForURL来获取有关文件系统对象(如应用程序、文档、文件夹或卷)的各种信息。
您可以提供文件系统引用或Core Foundation URL引用(带有方案file)来标识感兴趣的项目,以及指定所需信息的标志字(LSRequestedInfo)和指向项目信息记录LSItemInfoRecord)的指针,以便在其中接收回信息。
此记录中的信息可以包括项目的文件类型、创建者签名、文件扩展名和描述项目属性的各种标志(参见项目信息)。

您可能会发现关于项目的其他两条有用的信息是它的显示名称(用于在屏幕上向用户显示它的名称)和它的种类字符串(例如在Finder的获取信息窗口或Finder列表视图的Kind列中使用,以表征项目的一般性质,例如ApplicationFolderAliasJPEG PictureQuickTime MovieFrameMaker Document)。
您可以使用Launch Services函数获取显示名称LSCopyDisplayNameForRefLSCopyDisplayNameForURL以及带有LSCopyKindStringForRefLSCopyKindStringForURLLSCopyKindStringForTypeInfoLSCopyKindStringForMIMEType的种类字符串。


2024-06-16(日)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/857719.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】基础IO_4

文章目录 六、基础I/O4. 动静态库 未完待续 六、基础I/O 4. 动静态库 既然我们能够成功创建静态库了,接下来我们将这个代码打包成动态库: shared: 表示生成共享库格式 fPIC:产生位置无关码(position independent code) 动态库库名规则&…

bug记录——C语言中运算符前假后面不执行

A&&B A为真&#xff0c;才会判断B&#xff0c; 所以如果B访问越界的情况下必有A为假&#xff0c;那么代码是正确的 像这里&#xff0c;当child 1 > n时&#xff0c;a[child 1]越界访问&#xff0c; 但由于&&前面判断了child 1 < n为假&#xff0c;所以…

IDEA快速入门02-快速入门

二、快速入门 2.1 打开IDEA,点击New一个项目 入口&#xff0c;依次打开 File -> New -> Project。 2.2 使用Spring Initializr方式构建Spring Boot项目 2.3 设置项目所属组、项目名称、java版本等 2.4 选择SpringBoot版本及依赖组件 点击Create进行创建。 2.6 创建成…

windows10远程桌面端口,Windows 10远程桌面端口修改的两个方法

在Windows 10系统中&#xff0c;远程桌面功能允许用户通过网络从一台计算机远程访问和控制另一台计算机。默认情况下&#xff0c;远程桌面服务使用的端口是3389。然而&#xff0c;出于安全考虑&#xff0c;许多管理员和用户希望修改这一默认端口。本指南将详细介绍如何在Window…

WPS没保存关闭了怎么恢复数据?4个方法(更新版)

想象一下&#xff0c;你正在用WPS奋笔疾书&#xff0c;灵感如泉水般涌出&#xff0c;突然间&#xff0c;电脑却跟你开了个玩笑——啪地一下&#xff0c;文档未保存就关闭了&#xff01;是不是感觉像是被泼了一盆冷水&#xff0c;所有的热情瞬间熄灭&#xff1f;别急&#xff0c…

代码随想录第31天|贪心算法

134. 加油站 参考 思路: 以每个油站相差作为判断, 比如: gas [5 8 2 8]cost [6 5 6 6] [-1 3 -4 2]错误 : 把相差最大点当作起点判断能否绕一圈 : 相加数组是否小于0局部最优: 当前累加rest[i]的和curSum一旦小于0&#xff0c;起始位置至少要是i1&#xff0c;因为从i…

SQLite数据库(数据库和链表双向转换)

文章目录 SQLite数据库一、SQLite简介1、SQLite和MySQL2、基于嵌入式的数据库 二、SQLite数据库安装三、SQLite的常用命令四、SQLite的编程操作1、SQLite数据库相关API&#xff08;1&#xff09;头文件&#xff08;2&#xff09;sqlite3_open()&#xff08;3&#xff09;sqlite…

vue3 computed与watch,watchEffect比较

相同点 都是要根据一个或多个响应式数据进行监听 不同点 computed 如要return回来一个新的响应式值&#xff0c;且这个值不允许直接修改&#xff0c;想要修改的话可以设置set函数&#xff0c;在函数里面去修改所依赖的响应式数据&#xff0c;然后计算属性值会基于其响应式依…

【秋招刷题打卡】Day02-二分系列之-二分查找

Day02-二分系列之-二分查找 前言 给大家推荐一下咱们的 陪伴打卡小屋 知识星球啦&#xff0c;详细介绍 >笔试刷题陪伴小屋-打卡赢价值丰厚奖励 < ⏰小屋将在每日上午发放打卡题目&#xff0c;包括&#xff1a; 一道该算法的模版题 (主要以力扣&#xff0c;牛客&#…

基于CPWM与DPWM综合调制的光伏逆变器

1. 光伏并网逆变器矢量控制 图 1 为光伏发电系统常用的逆变器拓扑结 构,太阳能光伏电池板发电所产生的直流电能接 入光伏并网逆变器直流侧。逆变器将电能逆变, 经过滤波器与隔离升压变压器连接,最终并入电 网。其中隔离变压器低压侧漏感与LC滤波器组 成LCL滤波。为便于分析…

android | studio的UI布局和代码调试 | UI调试 (用于找到项目源码)

网上找到一个项目&#xff0c;想快速的搞懂是怎么实现的&#xff0c;搞了半天发现原来android都升级到Jetpack Compose了&#xff0c;然后去找源码挺不容易的&#xff0c;摸索中发现了这个调试的方法&#xff0c;还可以。 https://developer.android.com/studio/debug/layout-i…

谷歌Chrome浏览器排查js内存溢出

1. 打开谷歌浏览器检查台 2. 点击memory 3. 点击开始快照录制&#xff0c;时隔一会儿录一次&#xff0c;多录几次 4. 进行快照对比

【C++】STL中优先级队列的使用与模拟实现

前言&#xff1a;在前面我们学习了栈和队列的使用与模拟实现&#xff0c;今天我们来进一步的学习优先级队列使用与模拟实现 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:高质量&#xff23;学习 &#x1f448; &#x1f4af;代码仓库:卫…

常见的8种排序(含代码):插入排序、冒泡排序、希尔排序、快速排序、简单选择排序、归并排序、堆排序、基数排序

时间复杂度O(n^2) 1、插入排序 (Insertion Sort) 从第一个元素开始&#xff0c;该元素可以认为已经被排序&#xff1b;取出下一个元素&#xff0c;在已经排序的元素序列中从后向前扫描&#xff1b;如果该元素&#xff08;已排序&#xff09;大于新元素&#xff0c;将该元素移到…

IPv6 address status lifetime

IPv6 地址状态转换 Address lifetime (地址生存期) 每个配置的 IPv6 单播地址都有一个生存期设置&#xff0c;该设置确定该地址在必须刷新或替换之前可以使用多长时间。某些地址设置为“永久”并且不会过期。“首选”和“有效”生存期用于指定其使用期限和可用性。 自动配置的…

vue中的状态管理

第1部分&#xff1a;引言 状态管理是应用中数据流动和变更的核心机制。在Vue应用中&#xff0c;状态管理不仅涉及到组件间的数据共享&#xff0c;还包括了数据的持久化、异步操作的处理等复杂场景。良好的状态管理策略可以提高应用的响应速度&#xff0c;降低组件间的耦合度&a…

分页查询前端对接

文章目录 添加角色修改角色当点击修改按钮后,那么就会弹出对话框,所以要设置显示为true点击修改的时候就是 要显示对话框 制作用户管理页面开发后端接口用户查询前端整合新增接口功能实现修改 添加角色 首先添加 添加表单的组件 那么总结一下 就是使用 组件 然后再使用变量接…

Python基础入门

目录 1. 什么是Python&#xff1f; 2. 安装Python 3. Python基础语法 4. 数据结构 5. 文件操作 6. Python标准库 总结 1. 什么是Python&#xff1f; Python是一种高级编程语言&#xff0c;由Guido van Rossum于1991年发布。它以其简单易读的语法和强大的功能而闻名&…

Nominatim免费的地址解析,逆地址解析,OpenStreetMap开源地图数据【全网最全】

视频学习地址 国内的一些地址解析供应商的API都开始付费了&#xff0c;就想找个免费的地址解析和逆地址解析的应用&#xff0c;最终选择了Nominatim OpenStreetMap 文章目录 一、选型1-1、数据源1-2、地理编码引擎2-1、初尝Nominatim2-1-1、地址解析2-1-2、逆地址解析 2-2、OS…

国内外大模型生态发展报告!

很多同学只知类似Check GPT或者说对国内的一些比较了解&#xff0c;对国外的不太了解&#xff0c;所以在这总结。 1 大模型的发展 左表 名称参数特点发布时间GPT-215亿英文底模&#xff0c;开源2019年Google T5110亿多任务微调, 开源2019年GPT-3.51750亿人工反馈微调2022年M…