当前位置: 首页 > 面试题库 >

使用进程名称获取另一个程序窗口的标题

徐皓君
2023-03-14
问题内容

这个问题可能很基本,但是我很难破解。我认为我必须在中使用某些内容ctypes.windll.user32。请记住,我几乎没有使用这些库甚至ctypes整个库的经验。

我已经使用此代码列出了所有窗口标题,但是我不知道如何更改此代码以获取具有进程名称的窗口标题:

import ctypes

EnumWindows = ctypes.windll.user32.EnumWindows
EnumWindowsProc = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int))
GetWindowText = ctypes.windll.user32.GetWindowTextW
GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW
IsWindowVisible = ctypes.windll.user32.IsWindowVisible

titles = []
def foreach_window(hwnd, lParam):
    if IsWindowVisible(hwnd):
        length = GetWindowTextLength(hwnd)
        buff = ctypes.create_unicode_buffer(length + 1)
        GetWindowText(hwnd, buff, length + 1)
        titles.append(buff.value)
    return True
EnumWindows(EnumWindowsProc(foreach_window), 0)

print(titles)

这段代码来自https://sjohannes.wordpress.com/2012/03/23/win32-python-getting-all-
window-titles/

如果我的问题不清楚,我想实现这样的目标(仅作为示例-我不是专门询问Spotify):

getTitleOfWindowbyProcessName("spotify.exe") // returns "Avicii - Waiting For Love" (or whatever the title is)

如果有多个使用相同进程名运行的窗口(例如,多个chrome窗口),则可能会导致复杂化

谢谢。

编辑 :为澄清起见,我需要一些代码,该代码采用进程名称并以字符串形式返回该进程拥有的窗口标题的列表(可能为空)。


问题答案:

在介绍所有内容之前,我想指出一下SO:通过ctypes从Python调用的C函数返回错误值(@CristiFati的回答)。在使用_CTypes_ 之前, 请先 阅读它。

这是我在评论中的意思:

import win32gui


def enumWindowsProc(hwnd, lParam):
    print win32gui.GetWindowText(hwnd)

win32gui.EnumWindows(enumWindowsProc, 0)

在下面,我粘贴了整个内容…由于我搞砸了安全设置(这是 XP !!!),因此无法在我现在使用的 PC 上正常工作,并且一堆 访问被拒绝(错误)代码: 5 )错误,但是在这里。 __

code00.py

#!/usr/bin/env python3

import sys
import os
import traceback
import ctypes
from ctypes import wintypes
import win32con
import win32api
import win32gui
import win32process


def enumWindowsProc(hwnd, lParam):
    if (lParam is None) or ((lParam is not None) and (win32process.GetWindowThreadProcessId(hwnd)[1] == lParam)):
        text = win32gui.GetWindowText(hwnd)
        if text:
            wStyle = win32api.GetWindowLong(hwnd, win32con.GWL_STYLE)
            if wStyle & win32con.WS_VISIBLE:
                print("%08X - %s" % (hwnd, text))


def enumProcWnds(pid=None):
    win32gui.EnumWindows(enumWindowsProc, pid)


def enumProcs(procName=None):
    pids = win32process.EnumProcesses()
    if procName is not None:
        bufLen = 0x100

        _OpenProcess = ctypes.windll.kernel32.OpenProcess
        _OpenProcess.argtypes = [wintypes.DWORD, wintypes.BOOL, wintypes.DWORD]
        _OpenProcess.restype = wintypes.HANDLE

        _GetProcessImageFileName = ctypes.windll.psapi.GetProcessImageFileNameA
        _GetProcessImageFileName.argtypes = [wintypes.HANDLE, wintypes.LPSTR, wintypes.DWORD]
        _GetProcessImageFileName.restype = wintypes.DWORD

        _CloseHandle = ctypes.windll.kernel32.CloseHandle
        _CloseHandle.argtypes = [wintypes.HANDLE] 
        _CloseHandle.restype = wintypes.BOOL

        filteredPids = ()
        for pid in pids:
            try:
                hProc = _OpenProcess(win32con.PROCESS_ALL_ACCESS, 0, pid)
            except:
                print("Process [%d] couldn't be opened: %s" % (pid, traceback.format_exc()))
                continue
            try:
                buf = ctypes.create_string_buffer(bufLen)
                _GetProcessImageFileName(hProc, buf, bufLen)
                if buf.value:
                    name = buf.value.decode().split(os.path.sep)[-1]
                    #print name
                else:
                    _CloseHandle(hProc)
                    continue
            except:
                print("Error getting process name: %s" % traceback.format_exc())
                _CloseHandle(hProc)
                continue
            if name.lower() == procName.lower():
                filteredPids += (pid,)
            _CloseHandle(hproc)
        return filteredPids
    else:
        return pids


def main(args):
    if args:
        procName = args[0]
    else:
        procName = None
    pids = enumProcs(procName)
    #print(pids)
    for pid in pids:
        enumProcWnds(pid)


if __name__ == "__main__":
    print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
    main(sys.argv[1:])

不用说:

  • 为了使此代码起作用,您需要以特权用户( Administrator )运行它;至少需要 SeDebugPrivilege ([MS.Docs]:Privilege Constants)。
  • 当进程以 32/64位 模式运行时(执行此代码的 python 进程以及该代码枚举的目标进程),可能会感到惊讶。

更新 #0

  • 更换了所有 的ctypes 通过电话 PyWin32
  • 改进算法
  • 修复了先前版本中的错误

code01.py

#!/usr/bin/env python3

import sys
import os
import traceback
import win32con as wcon
import win32api as wapi
import win32gui as wgui
import win32process as wproc


# Callback
def enum_windows_proc(wnd, param):
    pid = param.get("pid", None)
    data = param.get("data", None)
    if pid is None or wproc.GetWindowThreadProcessId(wnd)[1] == pid:
        text = wgui.GetWindowText(wnd)
        if text:
            style = wapi.GetWindowLong(wnd, wcon.GWL_STYLE)
            if style & wcon.WS_VISIBLE:
                if data is not None:
                    data.append((wnd, text))
                #else:
                    #print("%08X - %s" % (wnd, text))


def enum_process_windows(pid=None):
    data = []
    param = {
        "pid": pid,
        "data": data,
    }
    wgui.EnumWindows(enum_windows_proc, param)
    return data


def _filter_processes(processes, search_name=None):
    if search_name is None:
        return processes
    filtered = []
    for pid, _ in processes:
        try:
            proc = wapi.OpenProcess(wcon.PROCESS_ALL_ACCESS, 0, pid)
        except:
            #print("Process {0:d} couldn't be opened: {1:}".format(pid, traceback.format_exc()))
            continue
        try:
            file_name = wproc.GetModuleFileNameEx(proc, None)
        except:
            #print("Error getting process name: {0:}".format(traceback.format_exc()))
            wapi.CloseHandle(proc)
            continue
        base_name = file_name.split(os.path.sep)[-1]
        if base_name.lower() == search_name.lower():
            filtered.append((pid, file_name))
        wapi.CloseHandle(proc)
    return tuple(filtered)


def enum_processes(process_name=None):
    procs = [(pid, None) for pid in wproc.EnumProcesses()]
    return _filter_processes(procs, search_name=process_name)


def main(*args):
    proc_name = args[0] if args else None
    procs = enum_processes(process_name=proc_name)
    for pid, name in procs:
        data = enum_process_windows(pid)
        if data:
            proc_text = "PId {0:d}{1:s}windows:".format(pid, " (File: [{0:s}]) ".format(name) if name else " ")
            print(proc_text)
            for handle, text in data:
                print("    {0:d}: [{1:s}]".format(handle, text))


if __name__ == "__main__":
    print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    main(*sys.argv[1:])
    print("\nDone.")

输出

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q031278590]>

“e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe” code01.py
Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916
64 bit (AMD64)] 64bit on win32

PId 8048 windows:
    131462: [Program Manager]
PId 10292 windows:
    133738: [Skype]
PId 5716 windows:
    89659824: [python - Get the title of a window of another program

using the process name - Stack Overflow - Google Chrome]
132978: [Service Name and Transport Protocol Port Number Registry -
Google Chrome]
329646: [CristiFati/Prebuilt-Binaries: Various software built on
various platforms. - Google Chrome]
133078: [unittest — Unit testing framework — Python 3.8.2
documentation - Google Chrome]
263924: [libssh2/libssh2 at libssh2-1.9.0 - Google Chrome]
264100: [WNetAddConnection2A function (winnetwk.h) - Win32 apps |
Microsoft Docs - Google Chrome]
525390: [Understanding 4D – The Tesseract - YouTube - Google
Chrome]
198398: [Workaround for virtual environments (VirtualEnv) by
CristiFati · Pull Request #1442 · mhammond/pywin32 - Google Chrome]
591586: [struct — Interpret bytes as packed binary data — Python
3.8.2 documentation - Google Chrome]
263982: [Simulating an epidemic - YouTube - Google Chrome]
329312: [SetHandleInformation function (handleapi.h) - Win32 apps |
Microsoft Docs - Google Chrome]
263248: [studiu functie faze - Google Search - Google Chrome]
198364: [Lambda expressions (since C 11) - cppreference.com -
Google Chrome]
PId 13640 windows:
984686: [Total Commander (x64) 9.22a - NOT REGISTERED]
44046462: [Lister - [c:\c\pula.txt]]
4135542: [Lister -
[e:\Work\Dev\CristiFati\Builds\Win\OPSWpython27\src\pywin32-b222\win32\src\win32process.i]]
3873800: [Lister -
[e:\Work\Dev\CristiFati\Builds\Win\OPSWpython27\src\pywin32-b222\win32\src\PyHANDLE.cpp]]
29825332: [Lister -
[E:\Work\Dev\Projects\DevTel\ifm\yosemite\GitLabA\yose\issues\buildnr\dependencies_200412.json]]
8329240: [Lister -
[e:\Work\Dev\Projects\DevTel\ifm\yosemite\src\svn\yosemite\CFATI_TRUNK_2\src\res\icpVerAppX.h]]
985026: [Lister -
[e:\Work\Dev\CristiFati\Builds\Win\OPSWpython27\src\pywin32-b222\win32\src\win32apimodule.cpp]]
PId 10936 windows:
264744: [Junk - cristian.fati@devtelsoftware.com - Mozilla
Thunderbird]
PId 10848 windows:
1115842: [Registry Editor]
PId 6164 windows:
264756: [Rocket.Chat]
PId 2716 windows:
854508: [Skype]
199310: [New tab and 5 more pages ‎- Microsoft Edge]
PId 14936 windows:
655466: [Administrator: C:\Windows\System32\cmd.exe]
PId 15132 windows:
526852: [Administrator: Cmd (064) -
“e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe”]
PId 15232 windows:
133918: [Microsoft Edge]
PId 9748 windows:
68492: [Microsoft Edge]
PId 14968 windows:
134146: [Microsoft Edge]
68634: [Microsoft Edge]
PId 15636 windows:
134208: [Microsoft Edge]
PId 16348 windows:
1379450: [Microsoft Edge]
PId 15568 windows:
68828: [Microsoft Edge]
68788: [Microsoft Edge]
PId 16040 windows:
265406: [Administrator: Cmd (032)]
PId 5792 windows:
2034532: [e:\Work\Dev\StackOverflow\q031278590\code00.py - Notepad

[Administrator]]
PId 12032 windows:
69134: [Microsoft Edge]
PId 16200 windows:
69146: [Microsoft Text Input Application]
PId 16224 windows:
69184: [Microsoft Edge]
PId 5288 windows:
265806: [Administrator: Cmd (064) -
“e:\Work\Dev\VEnvs\py_pc032_03.07.06_test0\Scripts\python.exe”]
PId 16476 windows:
265814: [Administrator: Cmd (064) -
“e:\Work\Dev\VEnvs\py_pc064_03.08.01_test0\Scripts\python.exe”]
PId 16612 windows:
331388: [Administrator: Cmd (064) - python]
PId 16796 windows:
592540: [Administrator: Cmd (064)]
PId 16880 windows:
264894: [Administrator: C:\Windows\System32\cmd.exe]
PId 17156 windows:
69284: [Console1 - Microsoft Visual Studio (Administrator)]
PId 16636 windows:
69396: [QtConsole0 - Microsoft Visual Studio (Administrator)]
PId 18380 windows:
69522: [Console0 - Microsoft Visual Studio (Administrator)]
PId 18108 windows:
200528: [BlackBird - Microsoft Visual Studio (Administrator)]
PId 19476 windows:
1052868: [pcbuild - Microsoft Visual Studio (Administrator)]
PId 16680 windows:
200924: [Yosemite - Microsoft Visual Studio (Administrator)]
PId 16020 windows:
201030: [-bash]
PId 6532 windows:
200996: [-bash]
PId 13140 windows:
266602: [-bash]
PId 6032 windows:
790834: [-bash]
PId 8496 windows:
8130950: [-bash]
PId 3208 windows:
4198878: [-bash]
PId 19088 windows:
528856: [-bash]
PId 12744 windows:
266770: [-bash]
PId 3896 windows:
201370: [-bash]
PId 11512 windows:
1315422: [Yosemite - Microsoft Visual Studio (Administrator)]
PId 20660 windows:
267028: [Yosemite - Microsoft Visual Studio (Administrator)]
PId 20684 windows:
70554: [Microsoft Visual Studio (Administrator)]
PId 14808 windows:
201692: [Dependency Walker]
PId 13056 windows:
5509836: [Oracle VM VirtualBox Manager]
PId 17756 windows:
70802: [TIC2Vone.pdf - Adobe Acrobat Reader DC]
PId 14572 windows:
267868: [Select Administrator: Powershell (064)]
PId 25588 windows:
332550: [Administrator: Cmd (064)]
PId 20504 windows:
463448: [Administrator: C:\Windows\System32\cmd.exe]
PId 24740 windows:
2298466: [Administrator: C:\Windows\System32\cmd.exe -
“e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe”]
PId 25960 windows:
2430020: [Utils [E:\Work\Dev\Utils] - …\current\ifm\pe_ver.py -
PyCharm (Administrator)]
PId 28836 windows:
332582: [E:\Work\Dev\Projects\DevTel\ifm\yosemite\src\svn\yosemite -
Log Messages - TortoiseSVN]
PId 29796 windows:
4724788: [Administrator: C:\Windows\System32\cmd.exe]
PId 26344 windows:
2883688: [Dependency Walker]
PId 34124 windows:
242746876: [Administrator: C:\Windows\System32\cmd.exe]
PId 21972 windows:
1317748: [Administrator: Cmd (064)]
PId 35060 windows:
2563162: [Administrator: C:\Windows\System32\cmd.exe -
“e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe” code00.py]
PId 14692 windows:
102695792: [Device Manager]
PId 35776 windows:
990338: [Process Explorer - Sysinternals: www.sysinternals.com
[CFATI-5510-0\cfati] (Administrator)]
PId 33524 windows:
656408: [PE Explorer - 30 day evaluation version]
25368616: [PE Explorer]
PId 29488 windows:
3218206: [Microsoft Edge]
PId 13184 windows:
267896: [cfati-ubtu16x64-0 [Running] - Oracle VM VirtualBox]
PId 33716 windows:
3932934: [Cheat Engine 7.0]
73098: [Cheat Engine 7.0]

Done.

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q031278590]>
[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q031278590]>

“e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe” code01.py
“notepad++.exe”
Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916
64 bit (AMD64)] 64bit on win32

PId 5792 (File: [C:\Install\pc064\NP++\NP++\Version\notepad++.exe])

windows:
2034532: [e:\Work\Dev\StackOverflow\q031278590\code00.py - Notepad++
[Administrator]]

Done.


 类似资料:
  • 我想知道一个应用程序的包名,我只知道那个应用程序的应用程序名。假设我想知道一个电子邮件应用程序的包名,只是它的名字,然后如何得到它 我只知道应用程序名。 这是代码,以获得所有的应用程序的包名称,但我需要知道特定的应用程序。

  • 我的数据库里有两个表叫做 编号列表和编号状态 我目前正在使用下面的查询获得完美的结果 现在我要number_list的名字。两个表都有编号是通用的。我已经尝试了一些左连接等,但我正在学习MySQL,所以没有得到适当的结果。如果有人能帮我做这件事,请告诉我。谢啦

  • 问题内容: 这应该很简单,但我只是没有看到。 如果我有一个进程ID,该如何使用它来获取有关该进程的信息,例如进程名称。 问题答案: 在Linux下,您可以读取proc文件系统。文件包含命令行。

  • 我正在构建一个模块,将数据保存到数据库中。完成模块后,我将把它做成一个JAR,这是常见的,任何人都会调用静态方法。有一个参数,它的名称是application name,我不想传递这个值,我想在向任何spring boot应用程序添加jar后动态获取这个值,然后任何人调用这个静态方法检索name application dynamic,所以spring boot包含应用程序属性have value

  • 使用Inspect.exe我可以看到应用程序组件的树结构中存在一个按钮,但我找不到获取该按钮句柄的方法。这是控件的Inspect.exe输出: 这个按钮的特殊之处在于它没有hwnd值。(hwnd: 0x0)。这是我试图获得对该按钮的引用的内容: 在本例中,hwnd变量是包含按钮的应用程序主窗口的句柄。 在阅读FindWindowEx的留档时,看起来似乎有多种方法可以使用不同的参数,我觉得我已经尝试

  • 问题内容: 我尝试了google,但是发现它获取了 当前 进程的父pid 。 我需要类似的东西,有这样的东西吗?基本上获取某些进程的pid,然后返回父进程的pid。 问题答案: 我认为最简单的方法是打开“ / proc”并解析内容。 您将找到ppid作为/ proc / pid / stat的第四个参数