MacOS下屏幕镜像设为独立显示器后如何获取一致的外接显示器信息?
问题描述
我希望在通过「屏幕镜像」->「用作独立显示器」连接外接显示器后,获取其供应商编号、eisaId等信息。但同一显示器通过HDMI接口或屏幕镜像扩展模式连接时,获取到的信息并不一致:
- HDMI连接时日志:
发现其他显示器 - ID: 19241XXXX, 名称: YYYY (供应商: 19ZZZ, 型号: 57WWW)
- 屏幕镜像-扩展模式时日志:
发现其他显示器 - ID: 41288XX, 名称: AAA (供应商: 163ZYYBBB, 型号: 16ZZWWYYY)
我尝试通过以下Core Graphics API获取显示器信息:
func configureDisplays() { var onlineDisplayIDs = [CGDirectDisplayID](repeating: 0, count: 16) var displayCount: UInt32 = 0 guard CGGetOnlineDisplayList(16, &onlineDisplayIDs, &displayCount) == .success else { os_log("Unable to get display list.", type: .info) return } for onlineDisplayID in onlineDisplayIDs where onlineDisplayID != 0 { let name = DisplayManager.getDisplayNameByID(displayID: onlineDisplayID) let id = onlineDisplayID let vendorNumber = CGDisplayVendorNumber(onlineDisplayID) let modelNumber = CGDisplayModelNumber(onlineDisplayID) let serialNumber = CGDisplaySerialNumber(onlineDisplayID) if !DEBUG_SW, DisplayManager.isAppleDisplay(displayID: onlineDisplayID) { let appleDisplay = AppleDisplay(id, name: name, vendorNumber: vendorNumber, modelNumber: modelNumber, serialNumber: serialNumber, isVirtual: isVirtual, isDummy: isDummy) os_log("Apple display found - %{public}@", type: .info, "ID: \(appleDisplay.identifier), Name: \(appleDisplay.name) (Vendor: \(appleDisplay.vendorNumber ?? 0), Model: \(appleDisplay.modelNumber ?? 0))") } else { let otherDisplay = OtherDisplay(id, name: name, vendorNumber: vendorNumber, modelNumber: modelNumber, serialNumber: serialNumber, isVirtual: isVirtual, isDummy: isDummy) os_log("Other display found - %{public}@", type: .info, "ID: \(otherDisplay.identifier), Name: \(otherDisplay.name) (Vendor: \(otherDisplay.vendorNumber ?? 0), Model: \(otherDisplay.modelNumber ?? 0))") } } }
请问当外接显示器通过HDMI接口和屏幕镜像扩展模式连接时,能否获取到一致的显示器信息?
解答
无法通过你当前使用的Core Graphics API获取到一致的显示器信息,核心原因在于两种连接模式的系统识别逻辑不同:
- HDMI直连时,系统直接读取显示器的EDID(扩展显示识别数据),
CGDisplayVendorNumber、CGDisplayModelNumber等API返回的是物理显示器的原生硬件参数。 - 屏幕镜像(AirPlay)扩展模式下,系统会创建一个虚拟显示设备,此时你拿到的ID、供应商编号、型号都是这个虚拟设备的参数——因为AirPlay的工作机制是将Mac画面编码传输,系统并未直接读取物理显示器的EDID数据。
如果想要尝试获取一致的物理显示器信息,有两个方向可探索:
- 底层IOKit API:通过
IOService相关接口遍历硬件设备树,尝试定位AirPlay连接对应的物理显示器节点,读取其EDID数据。但这种方法需要深入IOKit开发,且兼容性依赖于显示器的AirPlay实现,可能不稳定。 - 特征匹配:通过显示器支持的分辨率、刷新率列表等特征做模糊关联,或者让用户手动确认两种连接方式对应的是同一台显示器,但这种方法可靠性不高。
内容的提问来源于stack exchange,提问作者Luu Minh
相关产品推荐
相关产品推荐

