本文主要是介绍D-Bus——注册system bus,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1. 注册代码
在qt项目中创建无窗口项目:
#include <QCoreApplication>
#include <QDBusConnection>
#include <QDBusInterface>
#include <QDBusError>
#include <QDebug>class TestObject : public QObject
{Q_OBJECT
public:TestObject() {registerSystemDBus();}void registerSystemDBus() {QDBusConnection systemBus = QDBusConnection::systemBus();if (!systemBus.isConnected()) {qDebug() << "Failed to connect to system bus:" << systemBus.lastError().message();return;}if (!systemBus.registerService("com.example.TestSystemdService")) {qDebug() << "Failed to register service:" << systemBus.lastError().message();return;}if (!systemBus.registerObject("/com/example/TestObject",this,QDBusConnection::ExportAllSlots)) {qDebug() << "Failed to register object:" << systemBus.lastError().message();return;}}public slots:void testMethod() {qDebug() << "testMethod called";}
};int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);TestObject testObject;return a.exec();
}#include "main.moc"
cmake_minimum_required(VERSION 3.14)project(systemd LANGUAGES CXX)set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core)
find_package(Qt5DBus)add_executable(systemdmain.cpp
)
target_link_libraries(systemd Qt${QT_VERSION_MAJOR}::Core Qt5::DBus)install(TARGETS systemdLIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
编译文件
cmake .. sudo make install
执行编译出的二进制文件,会报如下错误:
root@redflag:/etc/dbus-1/system.d# ./systemd Failed to register service: "Connection \":1.8\" is not allowed to own the service \"com.example.TestSystemdService\" due to security policies in the configuration file"
这个错误消息表明当前 D-Bus 安全策略配置不允许应用程序注册服务 com.example.TestSystemdService。需要修改 D-Bus 的配置文件,以允许该服务的注册。
以下是一个详细的步骤,确保正确配置 D-Bus 以允许注册服务:
首先,创建一个新的 D-Bus 配置文件,例如 com.example.conf,并将其放置在 /etc/dbus-1/system.d/ 目录中:
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig><policy user="root"><allow own="com.example.TestSystemdService"/></policy>
</busconfig>
这个配置文件允许 root 用户拥有服务 com.example.TestSystemdService。将上述内容保存为 /etc/dbus-1/system.d/com.example.conf。为了使新的配置文件生效,需要重启 D-Bus 守护进程:
sudo systemctl restart dbus
确保配置文件 /etc/dbus-1/system.d/com.example.conf 的权限是正确的,使 D-Bus 守护进程能够读取该文件:
sudo chmod 644 /etc/dbus-1/system.d/com.example.conf
sudo chown root:root /etc/dbus-1/system.d/com.example.conf
现在,再次运行你的程序,确保 D-Bus 服务可以成功注册。
按照上述处理后,会报错
Error org.freedesktop.DBus.Error.ServiceUnknown: The name com.example.TestSystemdService was not provided by any .service files
问题可能出在几个方面,尤其是服务文件的位置和权限。
D-Bus 服务文件应该放在 /usr/share/dbus-1/system-services/ 目录下。确保文件名和内容正确,例如:
[D-Bus Service]
Name=com.example.TestSystemdService
Exec=/path/to/your/executable
User=root
注意这里的Exec 正常的家目录即可,不需要在root目录下,在root目录下会始终无法启动
确保服务文件的权限和所有者正确:
sudo chmod 644 /usr/share/dbus-1/system-services/com.example.TestSystemdService.service
sudo chown root:root /usr/share/dbus-1/system-services/com.example.TestSystemdService.service
确保你的可执行文件路径正确并且可执行:
sudo chmod +x /path/to/your/executable
重启 D-Bus 守护进程以确保新配置生效:
sudo systemctl restart dbus
在放置了服务文件并重启 D-Bus 后,确保你的可执行文件正在运行中:
sudo /path/to/your/executable
然后,在另一个终端中运行:
dbus-send --system --dest=com.example.TestSystemdService --print-reply /com/example/TestObject com.example.TestSystemdService.testMethod
验证 D-Bus 服务是否已注册,可以使用以下命令:
busctl --system list | grep com.example.TestSystemdService
如果问题依然存在,以下是一些调试步骤:
查看 D-Bus 日志以获取更多调试信息:
sudo journalctl -u dbus
在运行你的可执行文件后,确保它没有崩溃或退出。你可以在代码中添加调试信息来确认程序是否正常运行并注册了服务。
确保服务文件的名称和路径与 D-Bus 配置一致,并且在服务文件中使用的 Exec 路径是正确的。
这篇关于D-Bus——注册system bus的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!