2

我目前正在尝试检测用户何时在 Linux 平台(特别是 Fedora 14-16、RedHat 4.7-6.x、CentOS 4-6、OpenSuse 10-11)上快速切换到另一个用户。我一直在寻找类似于 Windows 上可用的 WTSRegisterSessionNotification() 函数的东西,但我遇到的只是一堆对 Wine 软件中错误的引用。

有没有其他人遇到过这个障碍?关于如何在 Windows 和 Mac OS X 上执行此操作似乎有大量资源(这很好),但在 Linux 上似乎什么都没有……

编辑:显然,在较新的系统(至少 Fedora 16)上,似乎是一个可行的选择。我想知道它是否有 DBus 接口...更多即将推出!

4

3 回答 3

1

首先,我需要告诉你我不是这方面的专家,但我有足够的知识给你指点,你可以去哪里学习更多。所以我在某些方面可能是错的。

我的猜测是:

  • 这并不容易
  • 对于您可能实施的大多数方法,可能有很多方法可以诱使他们相信不正确的东西,这可能会导致安全问题
  • 您的方法可能取决于:
    • 选择的 Linux 发行版
    • 发行版
    • 桌面环境
    • 显示管理器

据我所知(如果在过去几年发生了一些变化,我可能会错),快速用户切换是通过在另一个 VT 上启动另一个 X 服务器来实现的。所以一种方法检测是否有多个 X 服务器在运行。

但是在很多情况下,有多个 X 服务器在运行,这并不是因为快速的用户切换。示例:多席位甚至简单的 Xephyr 登录。使用 Xephyr 和 XDMCP,您甚至可以让同一用户在非快速用户切换情况下登录两次。

我开始搜索这个并找到了这个旧网页:

如果从那时起事情没有改变,您应该研究 ConsoleKit 和 PolicyKit(以及今天的 DeviceKit 和 Systemd)以及它们的 DBus API。

还有命令ck-list-sessionsck-launch-session。但我相信你可以很容易地欺骗这些命令:try tock-launch-session xterm然后ck-list-session.

您究竟为什么要检测快速用户切换?你的最终目标是什么?也许您可以在不尝试检测快速用户切换的情况下解决您的问题...

于 2012-05-16T12:32:33.470 回答
0

看来获取这些信息最有用的方法是使用ConsoleKit DBus 接口

以下过程概述了如何枚举会话并确定它们是否处于活动状态:

1.) 使用以下方法枚举会话:

    Bus:    org.freedesktop.ConsoleKit
    Path:   /org/freedesktop/ConsoleKit/Manager
    Method: org.freedesktop.ConsoleKit.Manager.GetSessions

返回的是一个导出 Session 接口的对象路径数组。反过来,可以使用 DBus 查询这些以获取其适当的属性。例如,我使用 dbus-send 与 ConsoleKit 通信以枚举我系统中的会话:

dbus-send --system --print-reply --dest=org.freedesktop.ConsoleKit /org/freedesktop/ConsoleKit/Manager org.freedesktop.ConsoleKit.Manager.GetSessions

我收到的回报如下:
method return sender=:1.15 -> dest=:1.205 reply_serial=2 array [ object path "/org/freedesktop/ConsoleKit/Session2" ]

2.)使用返回的对象路径,我可以查询它们的属性,例如它们是否处于活动状态,使用以下内容:

    Bus:    org.freedesktop.ConsoleKit
    Path:   /org/freedesktop/ConsoleKit/Session2
    Method: org.freedesktop.ConsoleKit.Session.IsActive

根据方法,我可以从会话中查询我需要的内容!使用 ConsoleKit 界面,我还可以检索当前会话的标识符,因此我可以随时查询它以查看它是否在需要时处于活动状态。只是为了好玩,这是以下命令的输出:

dbus-send --system --print-reply --dest=org.freedesktop.ConsoleKit /org/freedesktop/ConsoleKit/Session2 org.freedesktop.ConsoleKit.Session.IsActive

方法返回发件人=:1.15 -> dest=:1.206 reply_serial=2 boolean true

整洁的。

于 2012-05-17T19:45:40.257 回答
0

您必须通过轮询来确保在所有机器上工作(您显然不必运行 DBus 来进行用户切换!)。

Solaris、HP-UX 和其他系统不会在控制台上进行用户切换。

支持的平台:linux、FreeBSD、AIX。Linux/BSD 使用虚拟终端;/dev/lft0如果您有兴趣,可以使用 AIX 。

假设您想在控制台上可靠且安全地运行应用程序,并在控制台切换到另一个 VT 时在新的活动 X 服务器上重新启动它。问题是您可能有也可能没有运行桌面环境(我们中的一些人使用 twm!)。会话可能不是通过登录管理器启动的(您可以在 linux 上执行 Ctrl-Alt-F2,登录并startx愉快地运行)。系统甚至可能没有安装 xdm/gdm/similar。

愚蠢的解决方案是唯一可靠的解决方案:每隔几秒钟,查询活动的虚拟终端是什么(VT_GETSTATE在 linux 上,VT_GETACTIVE在 BSD 上)。如果它发生了变化,你就知道发生了变化。如果您切换到非图形会话(例如使用 Ctrl-Alt-F1),则不会有 X 服务器处于活动状态。

否则,您必须努力寻找哪个显示号码处于活动状态。例如,您可能会在 中看到两个 X 服务器ps,显示编号为 :1 和 :2。其中哪一个在VT7上?拼图的最后一块,将 VT 数字映射到显示数字,是最难的。这个问题在这个重复的问题中得到了回答,“给定的 X 进程在哪个虚拟终端上运行?” .

于 2013-02-14T11:48:12.930 回答