macOS 的 Launch Services 用于關(guān)聯(lián)應(yīng)用程序和文件并維護(hù)最近打開(kāi)的項(xiàng)目列表。
在文件關(guān)聯(lián)和右鍵菜單方面,每當(dāng)系統(tǒng)安裝一個(gè)新的應(yīng)用程序,都會(huì)調(diào)用 Launch Services 的 API 注冊(cè)關(guān)聯(lián)的文件類型。有兩種情況冀惭,一種是通過(guò) pkg 安裝包安裝的震叙,通常這些應(yīng)用程序會(huì)通過(guò)腳本主動(dòng)向 Launch Services 注冊(cè);而第二種常見(jiàn)的拖拽式 app 應(yīng)用程序散休,則是由 Finder 和系統(tǒng)通過(guò)對(duì)應(yīng)用程序的的一些判斷后代理注冊(cè)的媒楼。應(yīng)用程序通過(guò) Launch Services 注冊(cè)以后,就和特定的支持文檔產(chǎn)生了關(guān)聯(lián)戚丸。
Launch Services 隸屬于 Application Services Framework 「包含一堆的應(yīng)用程序接口划址,開(kāi)發(fā)者可以通過(guò)這些接口,調(diào)用系統(tǒng)服務(wù)」限府,用于使一個(gè)運(yùn)行中的程序夺颤,能夠打開(kāi)另一個(gè)程序、文檔胁勺、URL 的接口世澜。它可以打開(kāi)另一個(gè)程序;在另一個(gè)程序中打開(kāi)文檔或 URL署穗;找到對(duì)于一個(gè)文檔或 URL 最適用的程序寥裂;為一個(gè)應(yīng)用程序注冊(cè)它可以關(guān)聯(lián)的文檔類型和 URL;獲得一個(gè)文件案疲、URL 等正確的顯示方式封恰,比如如何顯示此類文件的圖標(biāo)以及信息等;維護(hù)和更新最近使用過(guò)的程序和文檔的列表络拌。
從原理上看俭驮,Launch Services 維護(hù)著一個(gè)文件到應(yīng)用程序之間的多對(duì)多對(duì)應(yīng)關(guān)系回溺,這個(gè)關(guān)系是存在一個(gè)數(shù)據(jù)庫(kù)中春贸。這個(gè)數(shù)據(jù)庫(kù)被稱作 Launch Services Database。對(duì)于 macOS 下的每一個(gè)文件都有描述信息「包括我們從 GetInfo 中看到的一些」遗遵。Launch Services 感興趣的萍恕,就是這個(gè)文件的文件類型碼、創(chuàng)建者簽名车要、文件擴(kuò)展名允粤、顯示名稱「用在 Finder 或 Dock 中顯示」、文件通用類型描述「比如翼岁,是應(yīng)用程序类垫、還是文件夾、或是替身琅坡、或是文件或視頻」悉患。除了這些,還有一些額外的「Meta Data 用于快速描述文件信息」標(biāo)志位榆俺。比如售躁,是否是可執(zhí)行程序坞淮、是否是容器「文件夾、包陪捷、卷回窘、dmg」、是否是隱藏文件等等市袖。而應(yīng)用程序方面啡直,Launch Services 會(huì)從應(yīng)用程序的 info.plist 中獲取諸如應(yīng)用程序名稱、圖標(biāo)苍碟、應(yīng)用程序可打開(kāi)的文件或 URL 類型付枫、運(yùn)行環(huán)境、是否有 UI驰怎、對(duì)應(yīng)權(quán)限等信息阐滩。Launch Services 就會(huì)根據(jù)這些信息,建立數(shù)據(jù)庫(kù)县忌,這就是右鍵點(diǎn)擊文件時(shí)掂榔,看到的可打開(kāi)此文件的應(yīng)用程序列表。當(dāng)然症杏,如果一個(gè)文件根本沒(méi)有任何匹配装获,右鍵菜單為空。Launch Services 會(huì)跳出窗口厉颤,讓用戶自行選擇應(yīng)用程序穴豫。用戶選擇后,Launch Services 就會(huì)將這個(gè)對(duì)應(yīng)關(guān)系保存在數(shù)據(jù)庫(kù)中逼友。
Launch Services 對(duì)于一個(gè)文件關(guān)聯(lián)多種應(yīng)用程序的時(shí)候精肃,也是有優(yōu)先級(jí)排序規(guī)則的。從右鍵菜單就可以看出帜乞,Launch Services 會(huì)有一個(gè)默認(rèn)選擇的應(yīng)用程序司抱。它的排序規(guī)則是:
用戶手動(dòng)指定的應(yīng)用程序擁有最高優(yōu)先級(jí)。
如果沒(méi)有指定黎烈,那么 Launch Services 會(huì)查看此文件擴(kuò)展名习柠,然后找到數(shù)據(jù)庫(kù)中所有跟此擴(kuò)展名相關(guān)的應(yīng)用程序。
如果沒(méi)有擴(kuò)展名照棋,或者第 2 步中找到多于一個(gè)的應(yīng)用程序资溃,Launch Services 會(huì)查找該文件是否含有文件類型碼,再按照此類型碼在數(shù)據(jù)庫(kù)中查找所有相關(guān)應(yīng)用程序烈炭。
如果通過(guò)第 2溶锭、3 步還是找到了多于一個(gè)的應(yīng)用程序,那么梳庆,首先查找哪些應(yīng)用程序注冊(cè)的創(chuàng)建者簽名和文件的創(chuàng)建者簽名匹配暖途,然后再查找哪些應(yīng)用程序是否是 macOS 原生應(yīng)用程序卑惜,再查找應(yīng)用程序是否是存在于系統(tǒng)啟動(dòng)卷上,再查找哪些應(yīng)用程序在本地卷上驻售,如果到這里還是剩下多于一個(gè)的應(yīng)用程序露久,就只能比版本號(hào)了。如果還是比不出來(lái)欺栗,那么 Launch Services 就會(huì)隨便排序了毫痕。
常見(jiàn)問(wèn)題
通常,我們?cè)?macOS 下會(huì)遇到重復(fù)菜單項(xiàng)的問(wèn)題迟几,或者某些已經(jīng)卸載的程序的菜單項(xiàng)遺留消请。從原因上來(lái)看,有三種可能:
除了 Launch Services 感興趣的項(xiàng)目外类腮,還有好多其他的項(xiàng)目也要被存儲(chǔ)在數(shù)據(jù)庫(kù)中臊泰。每當(dāng) Launch Services 要注冊(cè)一個(gè)新應(yīng)用程序時(shí),它會(huì)先看這個(gè)應(yīng)用程序中有沒(méi)有一個(gè) inUpdate 的描述蚜枢,如果此描述值為 1「就是 Yes」缸逃,那么 Launch Services 會(huì)查找數(shù)據(jù)庫(kù)進(jìn)行匹配。匹配到后會(huì)用這個(gè)新應(yīng)用程序的信息來(lái)更新這個(gè)舊的信息厂抽。如果 inUpdate 為 0需频,那么 Launch Services 會(huì)直接注冊(cè)這個(gè)應(yīng)用程序并關(guān)聯(lián)文件。這可能是潛在的重復(fù)項(xiàng)出現(xiàn)原因筷凤。
有些裝在虛擬機(jī)的應(yīng)用程序昭殉,在虛擬機(jī)卸載后也會(huì)殘留到 Launch Services 數(shù)據(jù)庫(kù)中。
應(yīng)用程序描述的一些更新變化藐守,使得 Launch Services 認(rèn)為這是一個(gè)全新的應(yīng)用程序而直接注冊(cè)挪丢。
以上三個(gè)方面都有可能造成重復(fù)菜單項(xiàng)的出現(xiàn),而且很難完全避免吗伤。
解決辦法
如果需要清理菜單重復(fù)項(xiàng)和無(wú)效的關(guān)聯(lián)吃靠,可以在終端運(yùn)行下面命令,在本地足淆、系統(tǒng)和用戶空間上,重建 Launch Services 數(shù)據(jù)庫(kù):
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -kill -r -domain local -domain system -domain user
lsregister命令參數(shù)如下:
-kill:重置全局 Launch Services 數(shù)據(jù)庫(kù)「最先執(zhí)行」
-lint:打印詳細(xì)應(yīng)用程序文件關(guān)聯(lián)注冊(cè)中的錯(cuò)誤信息
-convert:將老數(shù)據(jù)庫(kù)中的信息注冊(cè)到新的 Launch Services 數(shù)據(jù)庫(kù)
-load:加載 Launch Services 插件
-lazy n:指定一個(gè)注冊(cè)等待時(shí)間
-r:遞歸的查找文件夾內(nèi)容以做關(guān)聯(lián)之用「不包括 pkg 類型文件和隱藏文件夾下的內(nèi)容」
-R:遞歸的查找文件夾內(nèi)容以做關(guān)聯(lián)之用「包括 pkg 類型文件和隱藏文件夾下的內(nèi)容」
-f:強(qiáng)制更新所有對(duì)應(yīng)注冊(cè)信息
-v:輸出 lsregister 運(yùn)行詳細(xì)信息
-dump:在注冊(cè)完成后顯示數(shù)據(jù)庫(kù)內(nèi)容
-h:顯示此幫助