列出 macOS 上的所有 NSPasteBoard 名称

List all NSPasteBoard names on macOS

有没有办法获取当前系统上所有 NSPasteBoard 及其名称的列表?

我想知道是否有一些可用的功能(即使是私有的API)来实现这一点。谢谢!

不,即使使用 private API,也没有执行此操作的功能。

pboard 程序 (/usr/libexec/pboard) 作为守护进程运行并管理所有共享粘贴板。 NSPasteboard class 使用 XPC 与 pboard 守护进程对话,因此要获得所有粘贴板的列表,pboard 需要通过响应粘贴板名称列表来处理一些 XPC 消息。

pboard程序非常简单:它初始化各种东西(日志、沙箱、调度队列、mach服务)然后调用__CFPasteboardStartServicingConnection,它实际上是在CoreFoundation框架中定义的。此函数最终通过调用 _CFHandlePasteboardXPCEvent.

来处理每个传入的 XPC 请求

在反汇编器中查看_CFHandlePasteboardXPCEvent(我使用的是Hopper),我们可以看到pboard支持的请求的完整列表:

com.apple.pboard.create
com.apple.pboard.get-counts
com.apple.pboard.barrier
com.apple.pboard.begin-generation
com.apple.pboard.has-entries
com.apple.pboard.register-entries
com.apple.pboard.request-data
com.apple.pboard.refresh-cache
com.apple.pboard.release
com.apple.pboard.unique-promise-file
com.apple.pboard.resolve-all-promises
com.apple.pboard.resolve-pboard-promises
com.apple.pboard.set-data-flags
com.apple.pboard.make-generation-local

None 其中有一个明显的名称,如 com.apple.pboard.get-pboard-names。查看它们的处理方式,几乎所有人所做的第一件事就是从事件中获取粘贴板名称并查找或创建具有该名称的粘贴板。

我发现唯一没有立即涉及按名称查找粘贴板的请求是 com.apple.pboard.resolve-all-promises,它实际上发送了有趣的消息 +[_CFPasteboardStore copyAllPasteboards]。但是,据我所知,它不会将结果或实际上任何结果发送回客户端。这是 copyAllPasteboards 选择器在 CoreFoundation 中的唯一用途。

因此,除非您使用调试器附加到 pboard 守护程序并四处寻找,否则您将找不到所有现有粘贴板的列表。 (使用调试器附加到 pboard 需要首先禁用 SIP,这需要启动您的恢复分区。)