如何列出dbus服务下的所有对象路径?

如何列出dbus服务下的所有对象路径?

这是一个后续问题可用的 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.ElementTreedbus:

#!/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.

这就像浏览硬盘驱动器的文件夹结构,其中对象路径“/”是根,每个节点都是子文件夹。这似乎是检索特定总线名称(服务)的对象路径并构造包含对象路径的集合的最佳方法

相关内容