使用 Python3 通过 python-dbus 在 Linux 上的屏幕保护程序状态
Screensaver status on Linux via python-dbus using Python3
基于 :
import dbus
bus = dbus.SessionBus()
screensaver = bus.get_object('org.gnome.ScreenSaver', '/')
print(bool(screensaver.GetActive()))
我正在尝试访问屏幕保护程序,因为这在 Ubuntu 18.04 中已更改,但这段代码给我以下错误:
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.UnknownMethod: No such interface '(null)' on object at path /
摘自 https://askubuntu.com/questions/623195/how-to-get-gnome-session-idle-time,我可以用这个回答我自己的问题:
import dbus
session_bus = dbus.SessionBus()
gnome_screensaver = 'org.gnome.ScreenSaver'
object_path = '/{0}'.format(gnome_screensaver.replace('.', '/'))
get_object = session_bus.get_object(gnome_screensaver, object_path)
get_interface = dbus.Interface(get_object, gnome_screensaver)
status = bool(get_interface.GetActive())
object_path 是通过替换创建的。用 /, 并用 get_object,
获取对象
我之前遗漏的是dbus.Interface,实际上在https://dbus.freedesktop.org/doc/dbus-python/tutorial.html#interfaces-and-methods
处引用了
编辑:
这捕获了所有可用的屏幕保护程序:
import dbus
session_bus = dbus.SessionBus()
screensaver_list = ['org.gnome.ScreenSaver',
'org.cinnamon.ScreenSaver',
'org.kde.screensaver',
'org.freedesktop.ScreenSaver']
for each in screensaver_list:
try:
object_path = '/{0}'.format(each.replace('.', '/'))
get_object = session_bus.get_object(each, object_path)
get_interface = dbus.Interface(get_object, each)
status = bool(get_interface.GetActive())
print(status)
except dbus.exceptions.DBusException:
pass
Scott 的编辑在我的 Ubuntu 18.04 机器上产生错误 运行 python3:
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NotSupported: This method is not implemented
我想所有可用屏保的代码应该是:
import dbus
session_bus = dbus.SessionBus()
screensaver_list = ['org.gnome.ScreenSaver',
'org.cinnamon.ScreenSaver',
'org.kde.screensaver',
'org.freedesktop.ScreenSaver']
for each in screensaver_list:
try:
object_path = '/{0}'.format(each.replace('.', '/'))
get_object = session_bus.get_object(each, object_path)
get_interface = dbus.Interface(get_object, each)
status = bool(get_interface.GetActive())
print(status)
except dbus.exceptions.DBusException:
pass
顺便说一句,C 中的相同练习会产生以下代码:
#include<dbus/dbus.h>
#include<stdbool.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int scrstat(DBusConnection* conn, const char* scrdbus) {
bool* retbl = NULL;
char* scrobj;
DBusMessage* msg;
DBusMessageIter MsgIter;
DBusPendingCall* pending;
int i;
scrobj = (char *) malloc((1+strlen(scrdbus))*sizeof(char));
strncpy(scrobj,"/", 2*sizeof(char));
strncat(scrobj,scrdbus,strlen(scrdbus)*sizeof(char));
for(i=0;i<strlen(scrobj);i++) {
if(scrobj[i] == '.') scrobj[i] = '/';
}
// create a new method call and check for errors
msg = dbus_message_new_method_call(scrdbus, // target for the method call
scrobj, // object to call on
scrdbus, // interface to call on
"GetActive"); // method name
if (NULL == msg) {
fprintf(stderr, "Message NULL.\n");
return(1);
}
// send message and get a handle for a reply
if (!dbus_connection_send_with_reply (conn, msg, &pending, -1)) { // -1 is default timeout
fprintf(stderr, "Out of memory.\n");
return(1);
}
if (NULL == pending) {
fprintf(stderr, "Pending call NULL.\n");
return(1);
}
// free message
dbus_message_unref(msg);
// block until we recieve a reply
dbus_pending_call_block(pending);
if(!dbus_message_iter_init(msg, &MsgIter)) { //msg is pointer to dbus message received
fprintf(stderr, "Message without arguments.\n");
return(1);
}
if (DBUS_TYPE_BOOLEAN == dbus_message_iter_get_arg_type(&MsgIter)){
dbus_message_iter_get_basic(&MsgIter, &retbl);//this function is used to read basic dbus types like int, string etc.
fprintf(stdout, retbl ? "Screensaver status: on.\n" : "Screensaver status: off.\n");
}
// free the pending message handle
dbus_pending_call_unref(pending);
free(scrobj);
return(0);
}
int main() {
const char* scrdbus[5];
scrdbus[0] = "org.cinnamon.ScreenSaver";
scrdbus[1] = "org.freedesktop.ScreenSaver";
scrdbus[2] = "org.gnome.ScreenSaver";
scrdbus[3] = "org.kde.Screensaver";
scrdbus[4] = NULL;
DBusConnection* conn;
DBusError err;
int i=0;
// initialise the errors
dbus_error_init(&err);
conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
if (dbus_error_is_set(&err)) {
fprintf(stderr, "Connection error (%s).\n", err.message);
dbus_error_free(&err);
}
if (NULL == conn) {
fprintf(stderr, "Connection NULL.\n");
return(1);
}
while(NULL != scrdbus[i]) {
scrstat(conn, scrdbus[i]);
i++;
}
dbus_connection_unref(conn);
return(0);
}
以上代码使用gcc编译:
gcc -pthread -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -o scrstat scrstat.c -ldbus-1
python3的美妙之处在于17行代码而不是98行。 C的美妙之处在于10毫秒的执行时间而不是128毫秒。
基于 :
import dbus
bus = dbus.SessionBus()
screensaver = bus.get_object('org.gnome.ScreenSaver', '/')
print(bool(screensaver.GetActive()))
我正在尝试访问屏幕保护程序,因为这在 Ubuntu 18.04 中已更改,但这段代码给我以下错误:
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.UnknownMethod: No such interface '(null)' on object at path /
摘自 https://askubuntu.com/questions/623195/how-to-get-gnome-session-idle-time,我可以用这个回答我自己的问题:
import dbus
session_bus = dbus.SessionBus()
gnome_screensaver = 'org.gnome.ScreenSaver'
object_path = '/{0}'.format(gnome_screensaver.replace('.', '/'))
get_object = session_bus.get_object(gnome_screensaver, object_path)
get_interface = dbus.Interface(get_object, gnome_screensaver)
status = bool(get_interface.GetActive())
object_path 是通过替换创建的。用 /, 并用 get_object,
获取对象我之前遗漏的是dbus.Interface,实际上在https://dbus.freedesktop.org/doc/dbus-python/tutorial.html#interfaces-and-methods
处引用了编辑:
这捕获了所有可用的屏幕保护程序:
import dbus
session_bus = dbus.SessionBus()
screensaver_list = ['org.gnome.ScreenSaver',
'org.cinnamon.ScreenSaver',
'org.kde.screensaver',
'org.freedesktop.ScreenSaver']
for each in screensaver_list:
try:
object_path = '/{0}'.format(each.replace('.', '/'))
get_object = session_bus.get_object(each, object_path)
get_interface = dbus.Interface(get_object, each)
status = bool(get_interface.GetActive())
print(status)
except dbus.exceptions.DBusException:
pass
Scott 的编辑在我的 Ubuntu 18.04 机器上产生错误 运行 python3:
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NotSupported: This method is not implemented
我想所有可用屏保的代码应该是:
import dbus
session_bus = dbus.SessionBus()
screensaver_list = ['org.gnome.ScreenSaver',
'org.cinnamon.ScreenSaver',
'org.kde.screensaver',
'org.freedesktop.ScreenSaver']
for each in screensaver_list:
try:
object_path = '/{0}'.format(each.replace('.', '/'))
get_object = session_bus.get_object(each, object_path)
get_interface = dbus.Interface(get_object, each)
status = bool(get_interface.GetActive())
print(status)
except dbus.exceptions.DBusException:
pass
顺便说一句,C 中的相同练习会产生以下代码:
#include<dbus/dbus.h>
#include<stdbool.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int scrstat(DBusConnection* conn, const char* scrdbus) {
bool* retbl = NULL;
char* scrobj;
DBusMessage* msg;
DBusMessageIter MsgIter;
DBusPendingCall* pending;
int i;
scrobj = (char *) malloc((1+strlen(scrdbus))*sizeof(char));
strncpy(scrobj,"/", 2*sizeof(char));
strncat(scrobj,scrdbus,strlen(scrdbus)*sizeof(char));
for(i=0;i<strlen(scrobj);i++) {
if(scrobj[i] == '.') scrobj[i] = '/';
}
// create a new method call and check for errors
msg = dbus_message_new_method_call(scrdbus, // target for the method call
scrobj, // object to call on
scrdbus, // interface to call on
"GetActive"); // method name
if (NULL == msg) {
fprintf(stderr, "Message NULL.\n");
return(1);
}
// send message and get a handle for a reply
if (!dbus_connection_send_with_reply (conn, msg, &pending, -1)) { // -1 is default timeout
fprintf(stderr, "Out of memory.\n");
return(1);
}
if (NULL == pending) {
fprintf(stderr, "Pending call NULL.\n");
return(1);
}
// free message
dbus_message_unref(msg);
// block until we recieve a reply
dbus_pending_call_block(pending);
if(!dbus_message_iter_init(msg, &MsgIter)) { //msg is pointer to dbus message received
fprintf(stderr, "Message without arguments.\n");
return(1);
}
if (DBUS_TYPE_BOOLEAN == dbus_message_iter_get_arg_type(&MsgIter)){
dbus_message_iter_get_basic(&MsgIter, &retbl);//this function is used to read basic dbus types like int, string etc.
fprintf(stdout, retbl ? "Screensaver status: on.\n" : "Screensaver status: off.\n");
}
// free the pending message handle
dbus_pending_call_unref(pending);
free(scrobj);
return(0);
}
int main() {
const char* scrdbus[5];
scrdbus[0] = "org.cinnamon.ScreenSaver";
scrdbus[1] = "org.freedesktop.ScreenSaver";
scrdbus[2] = "org.gnome.ScreenSaver";
scrdbus[3] = "org.kde.Screensaver";
scrdbus[4] = NULL;
DBusConnection* conn;
DBusError err;
int i=0;
// initialise the errors
dbus_error_init(&err);
conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
if (dbus_error_is_set(&err)) {
fprintf(stderr, "Connection error (%s).\n", err.message);
dbus_error_free(&err);
}
if (NULL == conn) {
fprintf(stderr, "Connection NULL.\n");
return(1);
}
while(NULL != scrdbus[i]) {
scrstat(conn, scrdbus[i]);
i++;
}
dbus_connection_unref(conn);
return(0);
}
以上代码使用gcc编译:
gcc -pthread -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -o scrstat scrstat.c -ldbus-1
python3的美妙之处在于17行代码而不是98行。 C的美妙之处在于10毫秒的执行时间而不是128毫秒。