Gnome Shell扩展无法获取UPower全部DBus属性的问题
在笔记本上执行以下命令:
gdbus introspect --system --dest org.freedesktop.UPower --object-path /org/freedesktop/UPower/devices/DisplayDevice
返回结果包含EnergyRate、Energy等完整属性集合。
我正在修改一个GNOME Shell扩展,初始化代码如下:
const BUS_NAME = 'org.freedesktop.UPower'; const OBJECT_PATH = '/org/freedesktop/UPower/devices/DisplayDevice'; const DisplayDeviceInterface = loadInterfaceXML('org.freedesktop.UPower.Device'); const PowerManagerProxy = Gio.DBusProxy.makeProxyWrapper(DisplayDeviceInterface); ... this._proxy = new PowerManagerProxy(Gio.DBus.system, BUS_NAME, OBJECT_PATH,
现有代码可正常访问State、Percentage等属性,示例:
let chargingState = this._proxy.State === UPower.DeviceState.CHARGING ? '-charging' : ''; let fillLevel = 10 * Math.floor(this._proxy.Percentage / 10);
根据UPower文档及gdbus返回结果,EnergyRate、Energy属性确实存在,但通过global.log("Energy: " + this._proxy.EnergyRate);访问时,属性值为undefined,请问原因是什么?
出现该问题的核心原因及对应解决方式如下:
接口XML文件缺失目标属性定义
loadInterfaceXML('org.freedesktop.UPower.Device')加载的XML文件可能版本老旧或不完整,未包含EnergyRate、Energy的属性定义。Gio.DBusProxy仅会为XML中明确定义的属性生成访问器,若XML无对应定义,代理对象自然不存在该属性。
解决:手动检查加载的XML文件,补充缺失的属性定义,或直接从系统UPower接口获取最新的完整XML内容替换。属性名大小写不匹配
D-Bus接口属性名严格区分大小写,gdbus返回的EnergyRate可能在XML文件中使用了不同的命名格式(如energy-rate、Energy_rate),导致代理生成的属性名与你访问的名称不一致。
解决:通过this._proxy.g_properties查看代理暴露的所有属性列表,确认目标属性的准确名称后再访问。代理未完成异步初始化
Gio.DBusProxy.makeProxyWrapper创建的代理为异步初始化模式,若在代理初始化完成前访问属性,会返回undefined。现有代码能正常访问State、Percentage,可能是因为这些属性的访问时机在初始化完成后的回调逻辑中,而你访问EnergyRate的时机过早。
解决:确保在代理初始化完成后再访问属性,比如在g-properties-changed信号回调中处理,或通过异步初始化的完成回调触发属性访问逻辑。属性仅在特定设备状态下可用
部分UPower属性仅在特定设备状态下才会被赋值(如EnergyRate仅在放电或充电状态时有有效值),若当前设备处于闲置或未触发该属性的状态,属性可能未被初始化,返回undefined。
解决:先检查当前设备的State属性,确认是否处于能获取目标属性的状态,或监听属性变化信号,待属性有值后再访问。
内容的提问来源于stack exchange,提问作者Tim Richardson

