# -*- coding: utf-8 -*- r'''启动被控端,把它的窗口标题都列出来(实测比翻代码快)。''' from __future__ import annotations import ctypes import os import subprocess import sys import time from ctypes import wintypes from pathlib import Path ROOT = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote") EXE = ROOT / "dist_exe" / "ykxmz" / "ykxmz.exe" user32 = ctypes.windll.user32 def windows_of(pid: int) -> list: out = [] @ctypes.WINFUNCTYPE(ctypes.c_bool, wintypes.HWND, wintypes.LPARAM) def cb(hwnd, _lp): wpid = wintypes.DWORD() user32.GetWindowThreadProcessId(hwnd, ctypes.byref(wpid)) if wpid.value == pid: length = user32.GetWindowTextLengthW(hwnd) buf = ctypes.create_unicode_buffer(length + 1) user32.GetWindowTextW(hwnd, buf, length + 1) cls = ctypes.create_unicode_buffer(256) user32.GetClassNameW(hwnd, cls, 256) rect = wintypes.RECT() user32.GetWindowRect(hwnd, ctypes.byref(rect)) out.append({ "hwnd": hwnd, "title": buf.value, "class": cls.value, "visible": bool(user32.IsWindowVisible(hwnd)), "size": (rect.right - rect.left, rect.bottom - rect.top), }) return True user32.EnumWindows(cb, 0) return out def main() -> int: data = ROOT / "_build" / "_shotdata2" data.mkdir(parents=True, exist_ok=True) env = dict(os.environ) env["YKXMZ_DATA"] = str(data) print(" 启动被控端(不带 --silent,应该出主窗口)") proc = subprocess.Popen([str(EXE), "--port", "8898"], cwd=str(ROOT), env=env, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) time.sleep(12) wins = windows_of(proc.pid) print(" 进程 PID=%d 的窗口(%d 个):" % (proc.pid, len(wins))) for w in wins: print(" hwnd=%d 可见=%s 大小=%s 类=%s" % (w["hwnd"], w["visible"], w["size"], w["class"])) print(" 标题: %r" % w["title"]) print() print(" 提醒:PyInstaller --onedir 启动后,真正跑 GUI 的可能是子进程。") print(" 所有 python/ykxmz 进程:") r = subprocess.run( ["powershell", "-NoProfile", "-Command", "Get-Process ykxmz,python -ErrorAction SilentlyContinue | " "ForEach-Object { $_.Id.ToString() + ' ' + $_.ProcessName }"], capture_output=True, text=True, timeout=60, encoding="utf-8", errors="replace") print(" " + (r.stdout or "").replace("\n", "\n ")) # 子进程的窗口也列一下 for line in (r.stdout or "").splitlines(): parts = line.split() if len(parts) == 2: try: child = int(parts[0]) except ValueError: continue if child == proc.pid: continue for w in windows_of(child): if w["visible"] and w["title"]: print(" [子进程 %d] hwnd=%d 大小=%s 标题=%r" % (child, w["hwnd"], w["size"], w["title"])) proc.terminate() try: proc.wait(timeout=10) except subprocess.TimeoutExpired: proc.kill() subprocess.run(["powershell", "-NoProfile", "-Command", "Get-Process ykxmz -ErrorAction SilentlyContinue | " "Stop-Process -Force"], capture_output=True, timeout=60) return 0 if __name__ == "__main__": sys.exit(main())