【问题标题】:Get the process of the active window with Python in LinuxLinux下用Python获取活动窗口的进程
【发布时间】:2018-03-19 14:04:34
【问题描述】:

借助这些

Get active window title in X

Obtain Active window using Python

我已经设法找出活动窗口的名称

import os, re, sys
from subprocess import PIPE, Popen

def get_active_window_title():

    root = Popen( ['xprop', '-root', '_NET_ACTIVE_WINDOW'], stdout = PIPE )
    stdout, stderr = root.communicate()

    m = re.search( b'^_NET_ACTIVE_WINDOW.* ([\w]+)$', stdout )

    if m is not None:
        window_id = m.group( 1 )
        window = Popen( ['xprop', '-id', window_id, 'WM_NAME'], stdout = PIPE )
        stdout, stderr = window.communicate()

        match = re.match( b'WM_NAME\(\w+\) = (?P<name>.+)$', stdout )
        if match is not None:
            return match.group( 'name' ).decode( 'UTF-8' ).strip( '"' )

    return 'Active window not found'

if __name__ == '__main__':
    print( get_active_window_title() )

不过,我也对控制窗口的进程的名称(firefox、rstudio...)感兴趣。

关于如何进行的任何想法?

【问题讨论】:

  • BTW X11 允许进程通过网络打开窗口,因此该进程甚至可能无法在本地运行。
  • 一些窗口名称当然也包含进程名称,但不是全部(例如终端)。此外,我的代码也找不到所有窗口名称(例如 RStudio)。
  • @AnttiHaapala,如果有帮助的话,目前我只对本地进程感兴趣。

标签: python linux process window


【解决方案1】:

感谢 @AnttiHaapala 和 @Steampunkery 的提示。基于它们,我设法将我的原始代码修改为答案。

使用xprop -root 我得到window_id

root = Popen( ['xprop', '-root', '_NET_ACTIVE_WINDOW'], stdout = PIPE )
stdout, stderr = root.communicate()
m = re.search( b'^_NET_ACTIVE_WINDOW.* ([\w]+)$', stdout )
window_id   = m.group( 1 )

使用window_idxprop -id,我得到了窗口名称("WM_NAME"):

window = Popen( ['xprop', '-id', window_id, 'WM_NAME'], stdout = PIPE )
stdout, stderr = window.communicate()
wmatch = re.match( b'WM_NAME\(\w+\) = (?P<name>.+)$', stdout )
windowname = wmatch.group( 'name' ).decode( 'UTF-8' ).strip( '"' )

以及进程的名称 ("WM_CLASS"):

processname1, processname2 = None, None
process = Popen( ['xprop', '-id', window_id, 'WM_CLASS'], stdout = PIPE )
stdout, stderr = process.communicate()
pmatch = re.match( b'WM_CLASS\(\w+\) = (?P<name>.+)$', stdout )
processname1, processname2 = pmatch.group( 'name' ).decode( 'UTF-8' ).split( ', ' )

带有一些错误检查等的完整代码:

import os, re, sys, time
from subprocess import PIPE, Popen


def get_activityname():

    root = Popen( ['xprop', '-root', '_NET_ACTIVE_WINDOW'], stdout = PIPE )
    stdout, stderr = root.communicate()
    m = re.search( b'^_NET_ACTIVE_WINDOW.* ([\w]+)$', stdout )

    if m is not None:

        window_id   = m.group( 1 )

        windowname  = None
        window = Popen( ['xprop', '-id', window_id, 'WM_NAME'], stdout = PIPE )
        stdout, stderr = window.communicate()
        wmatch = re.match( b'WM_NAME\(\w+\) = (?P<name>.+)$', stdout )
        if wmatch is not None:
            windowname = wmatch.group( 'name' ).decode( 'UTF-8' ).strip( '"' )

        processname1, processname2 = None, None
        process = Popen( ['xprop', '-id', window_id, 'WM_CLASS'], stdout = PIPE )
        stdout, stderr = process.communicate()
        pmatch = re.match( b'WM_CLASS\(\w+\) = (?P<name>.+)$', stdout )
        if pmatch is not None:
            processname1, processname2 = pmatch.group( 'name' ).decode( 'UTF-8' ).split( ', ' )
            processname1 = processname1.strip( '"' )
            processname2 = processname2.strip( '"' )

        return {
            'windowname':   windowname,
            'processname1': processname1,
            'processname2': processname2
            }

    return {
        'windowname':   None,
        'processname1': None,
        'processname2': None
        }


if __name__ == '__main__':
    a = get_activityname()
    print( '''
    'windowname':   %s,
    'processname1': %s,
    'processname2': %s
    ''' % ( a['windowname'], a['processname1'], a['processname2'] ) )

这应该返回窗口的名称以及控制进程。它甚至可以获取 RStudio 的进程名称,由于某种原因,它没有窗口名称 ("WM_NAME")。

【讨论】:

    【解决方案2】:

    看看this 的答案。它使用一个名为xprop 和一个名为wmctrl 的命令行工具来获取活动窗口的PID。一旦你有了 PID,你就可以得到你想要的关于这个过程的任何信息。例如,要获取进程的名称,可以使用 python subprocess 模块执行以下命令:

    ps -p 1337 -o comm=
    

    上面会给你命令的名字,而这个:

    ps -p 1337 -o command=
    

    会给你命令的完整路径。

    示例(Ubuntu 17.10):

    命令:

    ps -p 1 -o comm=
    

    输出:

    init
    

    命令:

    ps -p 1 -o command=
    

    输出:

    /sbin/init
    

    【讨论】:

      猜你喜欢
      • 2012-05-03
      • 2018-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-12
      • 2011-01-05
      • 1970-01-01
      • 2013-02-06
      相关资源
      最近更新 更多