Pythonでウィンドウのタイトルを列挙する

2022/01/29 categories:Python| tags:Python|tasklist|ctypes|EnumWindows|

Pythonでウィンドウのタイトルを列挙するプログラムを作ってみました。

ctypesのEnumWindowsを使用してウィンドウのタイトルを列挙

EnumWindowsとGetWindowTextLengthWを使用してウィンドウタイトルを列挙してみました。

Pythonコード

import ctypes
from ctypes import wintypes
from collections import namedtuple

def list_windows():
    user32 = ctypes.windll.user32
    WindowInfo = namedtuple('WindowInfo', 'pid title')
    WNDENUMPROC = ctypes.WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM,)
    result = []
    def enum_proc(hWnd, lParam):
        if user32.IsWindowVisible(hWnd):
            pid = wintypes.DWORD()
            tid = user32.GetWindowThreadProcessId(hWnd, ctypes.byref(pid))
            length = user32.GetWindowTextLengthW(hWnd) + 1
            title = ctypes.create_unicode_buffer(length)
            user32.GetWindowTextW(hWnd, title, length)
            result.append([pid.value, title.value])
        return True
    user32.EnumWindows(WNDENUMPROC(enum_proc), 0)
    return sorted(result, key=lambda x:x[1])

if __name__ == '__main__':
    print( '\n'.join([ '{}, {}'.format(i, j) for i, j in list_windows() ]) )

実行結果

以下のように、プロセスIDとウィンドウタイトルが表示されます

8592, YouTube - Google Chrome
2100, コマンド プロンプト
10812, コマンド プロンプト

subprocessでtasklistを実行してウィンドウのタイトルを列挙

subprocessでtasklistを実行して、返ってきた文字列を処理することで、ウィンドウタイトルなどを取得してみました。文字列の処理が面倒なので、EnumWindowsを使用する方が良いかもしれません。

Pythonコード

import subprocess

def get_tasks():
    startupinfo = subprocess.STARTUPINFO()
    startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
    startupinfo.wShowWindow = subprocess.SW_HIDE
    
    proc = subprocess.Popen(['tasklist', '/v'], startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    result = proc.communicate()[0].decode('cp932')
    lines = result.splitlines()

    line2_splited = lines[2]
    indexes = [ i for i, c in enumerate(line2_splited) if c == ' ' ]
    indexes = [ [indexes[i] + 1, indexes[i+1]] for i in range(len(indexes)-1) ]
    indexes = [[0, indexes[0][0] - 1]] + indexes + [[ indexes[-1][-1] + 1, len(line2_splited) ]]

    titles = lines[1].split()
    titles = titles[:-4] + [ '{} {}'.format(titles[-4], titles[-3]) ] + [ '{} {}'.format(titles[-2], titles[-1]) ]
    tasks = []
    for line in lines[3:]:
        task = { title : line[index[0]:index[1]].strip() for index, title in zip(indexes, titles) }
        tasks.append(task)
    return tasks

if __name__ == '__main__':
    tasks = get_tasks()
    for task in tasks:
        print(task)

実行結果

{'イメージ名': 'chrome.exe', 'PID': '8592', 'セッション名': 'Console', 'セッション#': '3', 'メモリ使用量': '290,888 K', '状態': 'Running', 'ユーザー名': '', 'CPU 時間': '0:03:11', 'ウィンドウ タイトル': 'YouTube - Google Chrome'}
{'イメージ名': 'cmd.exe', 'PID': '2100', 'セッション名': 'Console', 'セッション#': '3', 'メモリ使用量': '4,668 K', '状態': 'Running', 'ユーザー名': '', 'CPU 時間': '0:00:00', 'ウィンドウ タイトル': 'コマンド プロンプト'}
{'イメージ名': 'cmd.exe', 'PID': '10812', 'セッション名': 'Console', 'セッション#': '3', 'メモリ使用量': '4,664 K', '状態': 'Running', 'ユーザー名': '', 'CPU 時間': '0:00:00', 'ウィンドウ タイトル': 'コマンド プロンプト'}

Share post

Related Posts

コメント