分类 默认分类 下的文章

macOS 的 Launch Services 用于关联应用程序和文件并维护最近打开的项目列表。

在文件关联和右键菜单方面,每当系统安装一个新的应用程序,都会调用 Launch Services 的 API 注册关联的文件类型。有两种情况,一种是通过 pkg 安装包安装的,通常这些应用程序会通过脚本主动向 Launch Services 注册;而第二种常见的拖拽式 app 应用程序,则是由 Finder 和系统通过对应用程序的的一些判断后代理注册的。应用程序通过 Launch Services 注册以后,就和特定的支持文档产生了关联。

Launch Services 隶属于 Application Services Framework 「包含一堆的应用程序接口,开发者可以通过这些接口,调用系统服务」,用于使一个运行中的程序,能够打开另一个程序、文档、URL 的接口。它可以打开另一个程序;在另一个程序中打开文档或 URL;找到对于一个文档或 URL 最适用的程序;为一个应用程序注册它可以关联的文档类型和 URL;获得一个文件、URL 等正确的显示方式,比如如何显示此类文件的图标以及信息等;维护和更新最近使用过的程序和文档的列表。

从原理上看,Launch Services 维护着一个文件到应用程序之间的多对多对应关系,这个关系是存在一个数据库中。这个数据库被称作 Launch Services Database。对于 macOS 下的每一个文件都有描述信息「包括我们从 GetInfo 中看到的一些」。Launch Services 感兴趣的,就是这个文件的文件类型码、创建者签名、文件扩展名、显示名称「用在 Finder 或 Dock 中显示」、文件通用类型描述「比如,是应用程序、还是文件夹、或是替身、或是文件或视频」。除了这些,还有一些额外的「Meta Data 用于快速描述文件信息」标志位。比如,是否是可执行程序、是否是容器「文件夹、包、卷、dmg」、是否是隐藏文件等等。而应用程序方面,Launch Services 会从应用程序的 info.plist 中获取诸如应用程序名称、图标、应用程序可打开的文件或 URL 类型、运行环境、是否有 UI、对应权限等信息。Launch Services 就会根据这些信息,建立数据库,这就是右键点击文件时,看到的可打开此文件的应用程序列表。当然,如果一个文件根本没有任何匹配,右键菜单为空。Launch Services 会跳出窗口,让用户自行选择应用程序。用户选择后,Launch Services 就会将这个对应关系保存在数据库中。

Launch Services 对于一个文件关联多种应用程序的时候,也是有优先级排序规则的。从右键菜单就可以看出,Launch Services 会有一个默认选择的应用程序。它的排序规则是:

  1. 用户手动指定的应用程序拥有最高优先级。
  2. 如果没有指定,那么 Launch Services 会查看此文件扩展名,然后找到数据库中所有跟此扩展名相关的应用程序。
  3. 如果没有扩展名,或者第 2 步中找到多于一个的应用程序,Launch Services 会查找该文件是否含有文件类型码,再按照此类型码在数据库中查找所有相关应用程序。
  4. 如果通过第 2、3 步还是找到了多于一个的应用程序,那么,首先查找哪些应用程序注册的创建者签名和文件的创建者签名匹配,然后再查找哪些应用程序是否是 macOS 原生应用程序,再查找应用程序是否是存在于系统启动卷上,再查找哪些应用程序在本地卷上,如果到这里还是剩下多于一个的应用程序,就只能比版本号了。如果还是比不出来,那么 Launch Services 就会随便排序了。

常见问题

通常,我们在 macOS 下会遇到重复菜单项的问题,或者某些已经卸载的程序的菜单项遗留。从原因上来看,有三种可能:

  • 除了 Launch Services 感兴趣的项目外,还有好多其他的项目也要被存储在数据库中。每当 Launch Services 要注册一个新应用程序时,它会先看这个应用程序中有没有一个 inUpdate 的描述,如果此描述值为 1「就是 Yes」,那么 Launch Services 会查找数据库进行匹配。匹配到后会用这个新应用程序的信息来更新这个旧的信息。如果 inUpdate 为 0,那么 Launch Services 会直接注册这个应用程序并关联文件。这可能是潜在的重复项出现原因。
  • 有些装在虚拟机的应用程序,在虚拟机卸载后也会残留到 Launch Services 数据库中。
  • 应用程序描述的一些更新变化,使得 Launch Services 认为这是一个全新的应用程序而直接注册。

以上三个方面都有可能造成重复菜单项的出现,而且很难完全避免。

解决办法

如果需要清理菜单重复项和无效的关联,可以在终端运行下面命令,在本地、系统和用户空间上,重建 Launch Services 数据库:

$ /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -kill -r -domain local -domain system -domain user

lsregister 命令参数如下:

-kill:重置全局 Launch Services 数据库「最先执行」
-lint:打印详细应用程序文件关联注册中的错误信息
-convert:将老数据库中的信息注册到新的 Launch Services 数据库
-load:加载 Launch Services 插件
-lazy n:指定一个注册等待时间
-r:递归的查找文件夹内容以做关联之用「不包括 pkg 类型文件和隐藏文件夹下的内容」
-R:递归的查找文件夹内容以做关联之用「包括 pkg 类型文件和隐藏文件夹下的内容」
-f:强制更新所有对应注册信息
-v:输出 lsregister 运行详细信息
-dump:在注册完成后显示数据库内容
-h:显示此帮助

1、下载 Office Tool Plus

Office Tool Plus 是一款强大且实用的 Office 部署工具。它基于 Office 部署工具OSPP 制作,可以很方便的部署、管理和激活 Office。

OTP 部署 Office 的步骤是先在它的部署页里选择好安装配置项,然后调用微软官方 Office 部署工具进行下载安装(通过微软官方通道下载)。这样保证了 100% 官方原汁原味,比外面的修改版、破解版要安全稳定得多。强烈推荐大家通过此工具安装 Office!

下载地址:https://otp.landian.vip/zh-cn/download.html

推荐下载包含框架的版本,可以直接运行。

2、安装 Office LTSC 专业增强版 2021 - 批量许可证

运行 OTP,按照下图选择安装配置项,点击右上角 开始部署

安装 Office LTSC 专业增强版 2021 - 批量许可证

3、安装许可证

在许可证管理里面选择对应的产品,点击安装许可证

安装许可证

4、设置 KMS

点开 KMS 管理,KMS 主机填 kms.03k.org,点击 保存设置

设置 KMS

5、激活

点击右上角 激活,大功告成!

有下面两个字典:

x = {'a': 1, 'b': 2}
y = {'b': 3, 'c': 4}

想要合并成一个字典:

z = {'a': 1, 'b': 3, 'c': 4}

有以下几种方法:

Python 3.9 以上:

z = x | y

Python 3.5 以上:

z = {**x, **y}

Python 3.4 以上、Python 2:

def merge_two_dicts(x, y):
    z = x.copy()  # 复制 x
    z.update(y)   # 合并 y
    return z

z = merge_two_dicts(x, y)

背景

今天服务器 Redis 服务突然报错

MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk. Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option). Please check the Redis logs for details about the RDB error.

网上搜索到解决方案是修改 redis.conf 配置文件,把 stop-writes-on-bgsave-error 设置为 no 即可。结果在保存配置文件的时候报错,提示磁盘已满。

后来发现罪魁祸首原来是 Docker 日志,有一个日志文件居然占了 23GB!

$ du -h $(find /var/lib/docker/containers/ -name *-json.log)
164M    /var/lib/docker/containers/1111/1111-json.log
60M     /var/lib/docker/containers/2222/2222-json.log
100M    /var/lib/docker/containers/3333/3333-json.log
12M     /var/lib/docker/containers/4444/4444-json.log
52K     /var/lib/docker/containers/5555/5555-json.log
23G     /var/lib/docker/containers/6666/6666-json.log

解决

1、清空日志文件

$ cat /dev/null > /var/lib/docker/containers/xxx/xxx-json.log
直接删除日志文件不能立即释放磁盘空间

2、全局日志设置

Docker 支持全局日志设置,但只对之后新建的容器有效。

$ vim /etc/docker/daemon.json
{
    .
    .
    .
    "log-driver": "json-file",
    "log-opts": {
        "max-size": "100m",
        "max-file": "3"
    }
}