程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了使用进程名称获取另一个程序窗口的标题大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决使用进程名称获取另一个程序窗口的标题?

开发过程中遇到使用进程名称获取另一个程序窗口的标题的问题如何解决?下面主要结合日常开发的经验,给出你关于使用进程名称获取另一个程序窗口的标题的解决方法建议,希望对你解决使用进程名称获取另一个程序窗口的标题有所启发或帮助;

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

这是我在评论中的意思:

import win32gui


def enumwindowsProc(hwnd, lParam):
    print win32gui.GetwindowText(hwnd)

win32gui.Enumwindows(enumwindowsProc, 0)

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

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)。@H_675_36@
  • 当进程以 32/64位 模式运行时(执行此代码的 python 进程以及该代码枚举的目标进程),可能会感到惊讶。@H_675_36@

更新 #0

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

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.")

解决方法

这个问题可能很基本,但是我很难破解。我认为我必须在中使用某些内容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窗口),则可能会导致复杂化

谢谢。


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

大佬总结

以上是大佬教程为你收集整理的使用进程名称获取另一个程序窗口的标题全部内容,希望文章能够帮你解决使用进程名称获取另一个程序窗口的标题所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。