首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Python获取活动窗口

使用Python获取活动窗口
EN

Stack Overflow用户
提问于 2012-04-22 16:08:05
回答 10查看 66.1K关注 0票数 44

我想让活动的窗口在屏幕上使用python。

例如,输入用户名和密码为admin的路由器的管理界面

这个管理界面就是我想使用python自动输入用户名和密码的界面。

为了做到这一点,我需要什么导入?

EN

回答 10

Stack Overflow用户

发布于 2012-06-21 23:01:17

在windows上,您可以使用python for windows extensions (http://sourceforge.net/projects/pywin32/):

代码语言:javascript
运行
复制
from win32gui import GetWindowText, GetForegroundWindow
print GetWindowText(GetForegroundWindow())

下面的代码是针对python 3的:

代码语言:javascript
运行
复制
from win32gui import GetWindowText, GetForegroundWindow
print(GetWindowText(GetForegroundWindow()))

(在http://scott.sherrillmix.com/blog/programmer/active-window-logger/上找到了这个)

票数 33
EN

Stack Overflow用户

发布于 2016-04-05 15:23:58

以下脚本应该可以在Linux、Windows和Mac上运行。它目前只在Linux (Ubuntu Mate Ubuntu 15.10)上进行测试。

先决条件

用于Linux的

安装wnck (在Ubuntu上安装sudo apt-get install python-wnck,参见libwnck)。

用于

确保win32gui可用

用于Mac

确保AppKit可用

脚本

代码语言:javascript
运行
复制
#!/usr/bin/env python

"""Find the currently active window."""

import logging
import sys

logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s',
                    level=logging.DEBUG,
                    stream=sys.stdout)


def get_active_window():
    """
    Get the currently active window.

    Returns
    -------
    string :
        Name of the currently active window.
    """
    import sys
    active_window_name = None
    if sys.platform in ['linux', 'linux2']:
        # Alternatives: https://unix.stackexchange.com/q/38867/4784
        try:
            import wnck
        except ImportError:
            logging.info("wnck not installed")
            wnck = None
        if wnck is not None:
            screen = wnck.screen_get_default()
            screen.force_update()
            window = screen.get_active_window()
            if window is not None:
                pid = window.get_pid()
                with open("/proc/{pid}/cmdline".format(pid=pid)) as f:
                    active_window_name = f.read()
        else:
            try:
                from gi.repository import Gtk, Wnck
                gi = "Installed"
            except ImportError:
                logging.info("gi.repository not installed")
                gi = None
            if gi is not None:
                Gtk.init([])  # necessary if not using a Gtk.main() loop
                screen = Wnck.Screen.get_default()
                screen.force_update()  # recommended per Wnck documentation
                active_window = screen.get_active_window()
                pid = active_window.get_pid()
                with open("/proc/{pid}/cmdline".format(pid=pid)) as f:
                    active_window_name = f.read()
    elif sys.platform in ['Windows', 'win32', 'cygwin']:
        # https://stackoverflow.com/a/608814/562769
        import win32gui
        window = win32gui.GetForegroundWindow()
        active_window_name = win32gui.GetWindowText(window)
    elif sys.platform in ['Mac', 'darwin', 'os2', 'os2emx']:
        # https://stackoverflow.com/a/373310/562769
        from AppKit import NSWorkspace
        active_window_name = (NSWorkspace.sharedWorkspace()
                              .activeApplication()['NSApplicationName'])
    else:
        print("sys.platform={platform} is unknown. Please report."
              .format(platform=sys.platform))
        print(sys.version)
    return active_window_name

print("Active window: %s" % str(get_active_window()))
票数 21
EN

Stack Overflow用户

发布于 2019-10-12 22:15:40

感谢Nuno André的回答,他展示了如何使用ctype与Windows进行交互。我已经使用他的提示编写了一个示例实现。

从v2.5开始,ctypes库就包含在Python中,这意味着几乎每个用户都有它。而且,它的界面比像win32gui (在撰写本文时最后一次更新是在2017年)这样的旧库和死库要干净得多。(2020年末更新:已死的win32gui库已通过重命名为而复活,因此,如果您想要一个维护的库,它现在再次是一个有效的选择。但是该库比我的代码慢6%。))

文档在这里:https://docs.python.org/3/library/ctypes.html (如果你想写自己的代码,你必须阅读它的用法帮助,否则你可能会导致分段故障崩溃,哈哈。)

基本上,ctype包括最常见的Windows DLL的绑定。下面是如何在纯Python中检索前台窗口的标题,而不需要外部库!只有内置的ctype!:-)

关于ctype最酷的事情是,你可以在谷歌上搜索任何你需要的Windows API,如果你想使用它,你可以通过ctype来实现!

Python3代码:

代码语言:javascript
运行
复制
from typing import Optional
from ctypes import wintypes, windll, create_unicode_buffer

def getForegroundWindowTitle() -> Optional[str]:
    hWnd = windll.user32.GetForegroundWindow()
    length = windll.user32.GetWindowTextLengthW(hWnd)
    buf = create_unicode_buffer(length + 1)
    windll.user32.GetWindowTextW(hWnd, buf, length + 1)
    
    # 1-liner alternative: return buf.value if buf.value else None
    if buf.value:
        return buf.value
    else:
        return None

性能非常好:我电脑上的0.01毫秒(0.00001秒)。

也可以在Python 2上工作,只需要做很小的改动。如果您使用的是Python2,我认为您只需删除类型注释(from typing import Optional-> Optional[str])。:-)

享受吧!

Win32技术说明:

length变量是以UTF16 (Windows Wide "Unicode")字符表示的实际文本的长度。(它不是字节数。)我们必须添加+ 1,以便为C样式字符串末尾的空终止符添加空间。如果我们不这样做,缓冲区中就没有足够的空间来容纳实际文本的最后一个真实字符,Windows将截断返回的字符串(它这样做是为了确保它适合非常重要的最终字符串Null-terminator)。

UTF函数为这么多create_unicode_buffer -16字符分配空间。

大多数(或全部?始终阅读Microsoft的MSDN文档!)与Unicode文本相关的Windows API将缓冲区长度作为字符,而不是字节。

还要仔细查看函数调用。有些以W结尾(例如GetWindowTextLengthW)。这代表“宽字符串”,这是Unicode字符串的Windows名称。进行这些W调用以获得正确的Unicode字符串(具有国际字符支持)是非常重要的。

PS: Windows使用Unicode已经有很长时间了。我知道Windows10完全是Unicode的,只想要W函数调用。我不知道老版本的Windows使用其他多字节字符串格式的确切截止日期,但我想那是在Windows Vista之前,谁在乎?旧的Windows版本(甚至7和8.1)已经死了,不受微软的支持。

再一次..。尽情享受!:-)

2020年末更新,Benchmark vs pywin32 库:

代码语言:javascript
运行
复制
import time

import win32ui

from typing import Optional
from ctypes import wintypes, windll, create_unicode_buffer

def getForegroundWindowTitle() -> Optional[str]:
    hWnd = windll.user32.GetForegroundWindow()
    length = windll.user32.GetWindowTextLengthW(hWnd)
    buf = create_unicode_buffer(length + 1)
    windll.user32.GetWindowTextW(hWnd, buf, length + 1)

    return buf.value if buf.value else None

def getForegroundWindowTitle_Win32UI() -> Optional[str]:
    # WARNING: This code sometimes throws an exception saying
    # "win32ui.error: No window is is in the foreground."
    # which is total nonsense. My function doesn't fail that way.
    return win32ui.GetForegroundWindow().GetWindowText()

iterations = 1_000_000

start_time = time.time()
for x in range(iterations):
    foo = getForegroundWindowTitle()
elapsed1 = time.time() - start_time
print("Elapsed 1:", elapsed1, "seconds")

start_time = time.time()
for x in range(iterations):
    foo = getForegroundWindowTitle_Win32UI()
elapsed2 = time.time() - start_time
print("Elapsed 2:", elapsed2, "seconds")

win32ui_pct_slower = ((elapsed2 / elapsed1) - 1) * 100
print("Win32UI library is", win32ui_pct_slower, "percent slower.")

在AMD Ryzen 3900x上执行多次运行后的典型结果:

我的函数: 4.5769994258880615秒

Win32UI库: 4.8619983196258545秒

Win32UI库的速度要慢6.226762715455125 %。

然而,差别很小,所以现在你可能想要使用这个库,因为它已经复活了(它之前在2017年就已经死了)。但是您必须处理该库奇怪的“没有窗口在前台”异常,我的代码不会受到这种异常的影响(请参阅基准测试代码中的代码注释)。

不管怎样..。享受吧!

票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10266281

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档