过滤后台进程 PyWin32

Filtering Background Processes PyWin32

我一直在努力从 EnumWindows 中过滤掉 windows,只包括最小化或打开到列表的 windows。

代码

def winEnumHandler(hwnd, ctx):
    title = win32gui.GetWindowText(hwnd)

    # Append HWND to list
    if win32gui.IsWindowVisible(hwnd) and title != '':
        app = ApplicationWindow(hwnd, title)
        applications.append(app)


def scanApplication():
    applications.clear()
    win32gui.EnumWindows(winEnumHandler, None)
    return applications

Expected/Actual

此代码的问题是它没有正确过滤掉通过 EnumWindows 找到的一些 windows 例如,目前我有:Chrome ,IDE,Discord 在我的电脑上打开,只希望它们出现在应用程序列表中。但是,我不仅得到那些 windows,还有后台任务,例如:计算器、邮件、Geforce 覆盖等...这些后台任务处于活动状态,但桌面上没有 window,也没有任何这些最小化。我怎样才能从 EnumWindows 中过滤掉后台任务?感谢阅读!

我 运行 对 DWM 进行了更多研究后,DWM 提供了一种方法,您可以查找 windows 的属性以从中获取更多信息。其中一个选项称为 cloak,它在从所有 windows 中过滤掉后台进程方面做得很好。我的代码如下。我还将 link 更详细地讨论 DWMA 的 Whosebug post。

def winEnumHandler(hwnd, ctx):
    # DWM
    isCloacked = ctypes.c_int(0)
    ctypes.WinDLL("dwmapi").DwmGetWindowAttribute(hwnd, 14, ctypes.byref(isCloacked), ctypes.sizeof(isCloacked))

    # Variables
    title = win32gui.GetWindowText(hwnd)

    # Append HWND to list
    if win32gui.IsWindowVisible(hwnd) and title != '' and isCloacked.value == 0:
        app = ApplicationWindow(hwnd, title)
        applications.append(app)

DWM 过滤:

从 link 中获取更多信息,这个最终解决方案展示了所有真实的 windows:

class TITLEBARINFO(ctypes.Structure):
    _fields_ = [("cbSize", ctypes.wintypes.DWORD), ("rcTitleBar", ctypes.wintypes.RECT),
                ("rgstate", ctypes.wintypes.DWORD * 6)]


def winEnumHandler(hwnd, ctx):
    # Title Info Initialization
    title_info = TITLEBARINFO()
    title_info.cbSize = ctypes.sizeof(title_info)
    ctypes.windll.user32.GetTitleBarInfo(hwnd, ctypes.byref(title_info))

    # DWM Cloaked Check
    isCloaked = ctypes.c_int(0)
    ctypes.WinDLL("dwmapi").DwmGetWindowAttribute(hwnd, 14, ctypes.byref(isCloaked), ctypes.sizeof(isCloaked))

    # Variables
    title = wg.GetWindowText(hwnd)

    # Append HWND to list
    if wg.IsWindowVisible(hwnd) and title != '' and isCloaked.value == 0:
        if not (title_info.rgstate[0] & wc.STATE_SYSTEM_INVISIBLE):
            app = ApplicationWindow(hwnd, title)
            applications.append(app)

任何简化请告诉我!谢谢!