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

这个问题可能是相当基本的,但我很难解开它。 我假设我将不得不在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) 

如果有多个窗口运行相同的进程名称(例如多个窗口),可能会出现一个复杂的问题,

谢谢。


编辑 :为了澄清,我想要一些代码,需要一个进程名称,并返回一个(可能是空的)该进程拥有的窗口标题列表作为string。

以下是我在评论中的含义:

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

下面,我粘贴了整个事情…它不适用于我现在的个人电脑,因为我搞砸了安全设置(这是一个XP的!!!),我得到了一堆访问被拒绝 (错误代码: 5 )错误,但这里是:

 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 bytes = wintypes.DWORD(bufLen) _OpenProcess = ctypes.cdll.kernel32.OpenProcess _GetProcessImageFileName = ctypes.cdll.psapi.GetProcessImageFileNameA _CloseHandle = ctypes.cdll.kernel32.CloseHandle filteredPids = () for pid in pids: try: hProc = _OpenProcess(wintypes.DWORD(win32con.PROCESS_ALL_ACCESS), ctypes.c_int(0), wintypes.DWORD(pid)) except: print("Process [%d] couldn't be opened: %s" % (pid, traceback.format_exc())) continue try: buf = ctypes.create_string_buffer(bufLen) _GetProcessImageFileName(hProc, ctypes.pointer(buf), ctypes.pointer(bytes)) 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,) 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__": main(sys.argv[1:]) 

不用说:

  • 为了使这个代码工作,你需要运行它作为一个特权用户(管理员); 至少需要SeDebugPrivilege 。
  • 当进程以32/64位模式运行时(您从中执行该代码的python进程以及由代码枚举的目标进程)可能会有些意外,