为什么 accountsservice 总是 return 一个空的用户列表?
Why does accountsservice always return an empty user list?
我试图获取 Vala 中的系统用户列表,但我得到的只是一个空列表。由于 Vala 文档非常简单,我不知道如何解决这个问题。这就是我正在尝试的:
var users_list = Act.UserManager.get_default ().list_users ();
看起来好像 UserManager
在创建时没有可用的数据。数据仅在 is_loaded
属性 为真时可用。
在 GLib 中,当 属性 发生变化时,可以发出 notify
信号。因此,我们将在以下工作示例中利用它:
int main () {
var loop = new EventLoop ();
var manager = new UserManager (loop);
if (!manager.is_running) {
print ("AccountsService is not running\n");
return 1;
}
loop.run ();
return 0;
}
class UserManager {
private Act.UserManager manager;
private EventLoop loop;
public bool is_running {
get { return !manager.no_service (); }
}
public UserManager (EventLoop event_loop) {
loop = event_loop;
manager = Act.UserManager.get_default ();
manager.notify["is-loaded"].connect( this.loaded );
}
void loaded (ParamSpec property) {
print (@"Property \"$(property.name)\" has changed\n");
this.print_users ();
this.loop.quit ();
}
void print_users () {
if (!manager.is_loaded) { return; }
print ("%-20s | %-20s\n", "User name", "Logged In Time");
foreach (var user in manager.list_users ()) {
print ("%-20s | %-20s\n",
user.user_name,
new DateTime.from_unix_local(user.login_time).to_string()
);
}
}
}
class EventLoop {
private MainLoop loop;
public EventLoop () {
loop = new MainLoop ();
}
public void run() {
this.loop.run ();
}
public void quit() {
Idle.add (()=> {
this.loop.quit ();
return Source.REMOVE;
});
}
}
该示例创建了一个 UserManager
class 来包装 AccountsService UserManager。假设用户管理器在 Act.UserManager.get_default ()
首次返回时从未加载,因此作为构造函数的一部分,当 is_loaded
属性 更改时设置回调。这是行:
manager.notify["is-loaded"].connect( this.loaded );
manager
有一个通知信号,当任何 属性 发生变化时都会发出通知信号。该示例使用信号详细信息仅在 is-loaded
属性 更改时触发。由于某种原因,它在名称中使用破折号而不是下划线。我找不到任何关于为什么会这样的文件。使用 notify
信号,回调可以将 ParamSpec
作为参数。这用于查找更改的 属性 的详细信息,但在示例中不再需要,因为使用了 "is-loaded"
信号详细信息。
该示例还创建了一个 EventLoop
class 作为 GLib 的 MainLoop
的包装器。 UserManager
具有 EventLoop
作为依赖项,因此事件循环可以退出并且程序完成。
另一种方法是直接从 Vala 使用 org.freedesktop.Accounts
D-Bus 服务。
我试图获取 Vala 中的系统用户列表,但我得到的只是一个空列表。由于 Vala 文档非常简单,我不知道如何解决这个问题。这就是我正在尝试的:
var users_list = Act.UserManager.get_default ().list_users ();
看起来好像 UserManager
在创建时没有可用的数据。数据仅在 is_loaded
属性 为真时可用。
在 GLib 中,当 属性 发生变化时,可以发出 notify
信号。因此,我们将在以下工作示例中利用它:
int main () {
var loop = new EventLoop ();
var manager = new UserManager (loop);
if (!manager.is_running) {
print ("AccountsService is not running\n");
return 1;
}
loop.run ();
return 0;
}
class UserManager {
private Act.UserManager manager;
private EventLoop loop;
public bool is_running {
get { return !manager.no_service (); }
}
public UserManager (EventLoop event_loop) {
loop = event_loop;
manager = Act.UserManager.get_default ();
manager.notify["is-loaded"].connect( this.loaded );
}
void loaded (ParamSpec property) {
print (@"Property \"$(property.name)\" has changed\n");
this.print_users ();
this.loop.quit ();
}
void print_users () {
if (!manager.is_loaded) { return; }
print ("%-20s | %-20s\n", "User name", "Logged In Time");
foreach (var user in manager.list_users ()) {
print ("%-20s | %-20s\n",
user.user_name,
new DateTime.from_unix_local(user.login_time).to_string()
);
}
}
}
class EventLoop {
private MainLoop loop;
public EventLoop () {
loop = new MainLoop ();
}
public void run() {
this.loop.run ();
}
public void quit() {
Idle.add (()=> {
this.loop.quit ();
return Source.REMOVE;
});
}
}
该示例创建了一个 UserManager
class 来包装 AccountsService UserManager。假设用户管理器在 Act.UserManager.get_default ()
首次返回时从未加载,因此作为构造函数的一部分,当 is_loaded
属性 更改时设置回调。这是行:
manager.notify["is-loaded"].connect( this.loaded );
manager
有一个通知信号,当任何 属性 发生变化时都会发出通知信号。该示例使用信号详细信息仅在 is-loaded
属性 更改时触发。由于某种原因,它在名称中使用破折号而不是下划线。我找不到任何关于为什么会这样的文件。使用 notify
信号,回调可以将 ParamSpec
作为参数。这用于查找更改的 属性 的详细信息,但在示例中不再需要,因为使用了 "is-loaded"
信号详细信息。
该示例还创建了一个 EventLoop
class 作为 GLib 的 MainLoop
的包装器。 UserManager
具有 EventLoop
作为依赖项,因此事件循环可以退出并且程序完成。
另一种方法是直接从 Vala 使用 org.freedesktop.Accounts
D-Bus 服务。