使用Python3通过python-dbus在Linux上的屏幕保护程序状态

问题描述 投票:1回答:2

基于https://stackoverflow.com/a/17981327/9614384

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 /
python linux ubuntu dbus screensaver
2个回答
1
投票

Scott的EDIT在运行python3的Ubuntu 18.04机器上产生错误:

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毫秒。


1
投票

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)
    except dbus.exceptions.DBusException:
        pass
status = bool(get_interface.GetActive())
print(status)
© www.soinside.com 2019 - 2024. All rights reserved.