这是一个后续问题可用的 DBus 服务列表。
以下 python 代码将列出所有可用的 DBus 服务。
import dbus
for service in dbus.SystemBus().list_names():
print(service)
我们如何在python中列出服务下的对象路径?如果答案不涉及 python 也没关系,尽管它是首选。
我使用的是Ubuntu 14.04
答案1
QT
设置提供了最方便的方法,通过qdbus
:
qdbus --system org.freedesktop.UPower
印刷
/
/org
/org/freedesktop
/org/freedesktop/UPower
/org/freedesktop/UPower/Wakeups
/org/freedesktop/UPower/devices
/org/freedesktop/UPower/devices/line_power_ADP0
/org/freedesktop/UPower/devices/DisplayDevice
/org/freedesktop/UPower/devices/battery_BAT0
至于Python的方式......根据官方文档(在下面标准接口):
有一些标准接口可能在各种 D-Bus 应用程序中有用。
org.freedesktop.DBus.Introspectable
该接口有一个方法:
org.freedesktop.DBus.Introspectable.Introspect (out STRING xml_data)
对象实例可以实现
Introspect
返回一个XML 对象的描述,包括其接口(带有信号和方法)、对象路径树中位于其下方的对象及其属性。
因此,这里有一个非常简单的示例,应该可以帮助您入门。它用xml.etree.ElementTree
和dbus
:
#!/usr/bin/env python
import dbus
from xml.etree import ElementTree
def rec_intro(bus, service, object_path):
print(object_path)
obj = bus.get_object(service, object_path)
iface = dbus.Interface(obj, 'org.freedesktop.DBus.Introspectable')
xml_string = iface.Introspect()
for child in ElementTree.fromstring(xml_string):
if child.tag == 'node':
if object_path == '/':
object_path = ''
new_path = '/'.join((object_path, child.attrib['name']))
rec_intro(bus, service, new_path)
bus = dbus.SystemBus()
rec_intro(bus, 'org.freedesktop.UPower', '/org/freedesktop/UPower')
org.freedesktop.UPower
它从eg开始递归内省/org/freedesktop/UPower
并打印所有对象路径(节点名称):
/org/freedesktop/UPower
/org/freedesktop/UPower/Wakeups
/org/freedesktop/UPower/devices
/org/freedesktop/UPower/devices/DisplayDevice
/org/freedesktop/UPower/devices/battery_BAT0
/org/freedesktop/UPower/devices/line_power_ADP0
如果你使用的话,这几乎就是你会得到的d-feet
(并不是你需要它):
答案2
我不确定您是否可以在 Python 中以编程方式执行此操作。你可能会,但弄清楚如何做会是一件非常头疼的事情。我以前尝试过这样做,但最终讨厌 Dbus。无论如何我建议使用D 脚如果你想调查事情。下面是我从我的电脑上偷来的截图博客。
一旦您知道了程序名称、对象路径等,您就可以使用 Python 来访问这些内容。
例子
progname = 'org.freedesktop.NetworkManager'
objpath = '/org/freedesktop/NetworkManager'
intfname = 'org.freedesktop.NetworkManager'
methname = 'GetDevices'
bus = dbus.SystemBus()
obj = bus.get_object(progname, objpath)
interface = dbus.Interface(obj, intfname) # Get the interface to obj
method = interface.get_dbus_method(methname) # The method on that interface
method() # And finally calling the method
如您所见,完成一件简单的事情是一件很痛苦的事情。但这是您可以使用 Dbus 获得的最简单的工作流程!
因此,使用 GUI 工具找出对象路径、接口等。然后使用上面的代码片段作为模板来访问这些东西。另外,我建议您通过 IPython 的解释器执行此操作,以查看每个对象具有哪些方法、属性等(通过点击选项卡)。
答案3
如果服务有一个对象实现org.freedesktop.DBus.ObjectManager
,则其方法GetManagedObjects
返回“单个方法调用中的所有对象、接口和属性。”例如,UDisks2就有这样一个对象。
答案4
根据我的经验,我知道获取总线名称(服务)的对象路径可以使用对象路径“/”进行内省,即(使用上面的示例)
introspectfunc('org.freedesktop.UPower', '/')
这应该返回:
<node name="/">
<node name="org"/>
<node name="org"/>
<node name="org"/>
<node name="org"/>
<node name="org"/>
<node name="org"/></node>
然后用路径'/org'进行内省
introspectfunc('org.freedesktop.UPower', '/org')
这应该返回:
<node name="/org">
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/></node>
等等:
introspectfunc('org.freedesktop.UPower', '/org/freedesktop')
introspectfunc('org.freedesktop.UPower', '/org/freedesktop/UPower')
etc.
这就像浏览硬盘驱动器的文件夹结构,其中对象路径“/”是根,每个节点都是子文件夹。这似乎是检索特定总线名称(服务)的对象路径并构造包含对象路径的集合的最佳方法