Skip to content

Instantly share code, notes, and snippets.

@SmileMachine
Created December 21, 2025 17:12
Show Gist options
  • Select an option

  • Save SmileMachine/818fafb53a1234888ab749f3ad153529 to your computer and use it in GitHub Desktop.

Select an option

Save SmileMachine/818fafb53a1234888ab749f3ad153529 to your computer and use it in GitHub Desktop.
import plistlib # 读取 plist 文件
import subprocess # 执行命令
def get_default_opener(ext):
# 获取当前的打开方式
result = subprocess.run(['duti', '-x', ext], capture_output=True, text=True)
if result.returncode != 0:
print(result.stderr)
return None
return result.stdout.split("\n")[0]
def set_default_opener(ext, opener, role):
# 设置默认的打开方式
result = subprocess.run(['duti', '-s', opener, ext, role], capture_output=True, text=True)
if result.returncode != 0:
print(result.stderr)
return False
return True
# 要把 From 相关的默认打开方式改成 To
FROM_APP= 'Cursor'
TO_APP= 'Visual Studio Code'
if __name__ == '__main__':
# 目标软件的 Info.plist 路径
path = f'/Applications/{TO_APP}.app/Contents/Info.plist'
with open(path, 'rb') as f:
plist = plistlib.load(f)
# 简单处理一下
ext_list = [{
'name': item['CFBundleTypeName'],
'ext': item['CFBundleTypeExtensions']
} for item in plist['CFBundleDocumentTypes']]
# 获取 bundle_id
bundle_id = plist['CFBundleIdentifier']
# 结果是类似这样的
# ext_list : [{'ext': ['h'], 'name': 'C header file'},
# {'ext': ['c'], 'name': 'C source code'},
# {'ext': ['gitattributes', 'gitconfig', 'gitignore'],
# 'name': 'Git configuration file'}, ...]
# bundle_id : 'com.todesktop.Cursor'
# 遍历所有扩展名,把 From 相关的改成 To
# 之所以不全改,是因为有些扩展名我已经自定义过了,比如 markdown 文件,我习惯用 Typora 打开。
# Html 文件,我习惯用浏览器打开,或者还有的 jetBrains 的一些 IDE 打开。
for item in ext_list[:]:
print(item['name'])
for i, ext in enumerate(item['ext']):
default_opener = get_default_opener(ext)
print(f' {ext} -> {default_opener}', end='')
if default_opener == FROM_APP:
print(f' -> {TO_APP}')
set_default_opener(ext, bundle_id, 'editor')
else:
print()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment