aw_watcher_window/windows.py
import os
import time
from typing import Optional
import win32api
import win32gui
import win32process
import wmi
def get_app_path(hwnd) -> Optional[str]:
"""Get application path given hwnd."""
path = None
_, pid = win32process.GetWindowThreadProcessId(hwnd)
process = win32api.OpenProcess(
0x0400, False, pid
) # PROCESS_QUERY_INFORMATION = 0x0400
try:
path = win32process.GetModuleFileNameEx(process, 0)
finally:
win32api.CloseHandle(process)
return path
def get_app_name(hwnd) -> Optional[str]:
"""Get application filename given hwnd."""
path = get_app_path(hwnd)
if path is None:
return None
return os.path.basename(path)
def get_window_title(hwnd):
return win32gui.GetWindowText(hwnd)
def get_active_window_handle():
hwnd = win32gui.GetForegroundWindow()
return hwnd
# WMI-version, used as fallback if win32gui/win32process/win32api fails (such as for "run as admin" processes)
c = wmi.WMI()
"""
Much of this derived from: http://stackoverflow.com/a/14973422/965332
"""
def get_app_name_wmi(hwnd) -> Optional[str]:
"""Get application filename given hwnd."""
name = None
_, pid = win32process.GetWindowThreadProcessId(hwnd)
for p in c.query("SELECT Name FROM Win32_Process WHERE ProcessId = %s" % str(pid)):
name = p.Name
break
return name
def get_app_path_wmi(hwnd) -> Optional[str]:
"""Get application path given hwnd."""
path = None
_, pid = win32process.GetWindowThreadProcessId(hwnd)
for p in c.query(
"SELECT ExecutablePath FROM Win32_Process WHERE ProcessId = %s" % str(pid)
):
path = p.ExecutablePath
break
return path
if __name__ == "__main__":
while True:
hwnd = get_active_window_handle()
print("Title:", get_window_title(hwnd))
print("App: ", get_app_name(hwnd))
print("App (wmi): ", get_app_name_wmi(hwnd))
print("Path: ", get_app_path(hwnd))
print("Path (wmi): ", get_app_path_wmi(hwnd))
time.sleep(1.0)