更新
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
"""
|
||||
企业微信 UI 完整诊断工具 v2
|
||||
同时使用 uiautomation + win32gui 两套方式诊断窗口结构
|
||||
运行方法:python inspect_tree.py
|
||||
"""
|
||||
import uiautomation as auto
|
||||
import win32gui
|
||||
import win32con
|
||||
import win32api
|
||||
|
||||
WX_WINDOW_CLASS = 'WeWorkWindow'
|
||||
|
||||
|
||||
def find_wx_window():
|
||||
root = auto.GetRootControl()
|
||||
for win in root.GetChildren():
|
||||
if WX_WINDOW_CLASS in win.ClassName:
|
||||
return win
|
||||
return None
|
||||
|
||||
|
||||
def print_uia_tree(ctrl, prefix="", depth=0, max_depth=3):
|
||||
"""打印 UIA 控件树"""
|
||||
try:
|
||||
ct = ctrl.ControlTypeName
|
||||
name = repr(ctrl.Name[:40]) if ctrl.Name else "''"
|
||||
cls = ctrl.ClassName
|
||||
aid = ctrl.AutomationId
|
||||
bound = ctrl.BoundingRectangle
|
||||
print(f"{prefix}[{ct}] Name={name} ClassName='{cls}' AutoId='{aid}' Rect=({bound.left},{bound.top},{bound.right},{bound.bottom})")
|
||||
except Exception as e:
|
||||
print(f"{prefix}[ERROR] {e}")
|
||||
return
|
||||
|
||||
if depth >= max_depth:
|
||||
return
|
||||
try:
|
||||
children = ctrl.GetChildren()
|
||||
for child in children:
|
||||
print_uia_tree(child, prefix + " ", depth + 1, max_depth)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def enum_all_child_hwnds(parent_hwnd):
|
||||
"""用 win32gui 递归枚举所有子窗口句柄"""
|
||||
results = []
|
||||
|
||||
def callback(hwnd, _):
|
||||
try:
|
||||
class_name = win32gui.GetClassName(hwnd)
|
||||
title = win32gui.GetWindowText(hwnd)
|
||||
rect = win32gui.GetWindowRect(hwnd)
|
||||
is_visible = win32gui.IsWindowVisible(hwnd)
|
||||
results.append({
|
||||
'hwnd': hwnd,
|
||||
'class': class_name,
|
||||
'title': title,
|
||||
'rect': rect,
|
||||
'visible': is_visible
|
||||
})
|
||||
except Exception:
|
||||
pass
|
||||
return True
|
||||
|
||||
win32gui.EnumChildWindows(parent_hwnd, callback, None)
|
||||
return results
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("=" * 60)
|
||||
print(" 企业微信 UI 完整诊断工具")
|
||||
print("=" * 60)
|
||||
|
||||
# ── 1. 找主窗口 ──────────────────────────────────────────────
|
||||
print("\n[1] 查找企业微信主窗口...")
|
||||
wx = find_wx_window()
|
||||
if not wx:
|
||||
print(" 未找到!请确认企业微信主窗口已在桌面上显示。")
|
||||
exit(1)
|
||||
|
||||
hwnd = wx.NativeWindowHandle
|
||||
rect = wx.BoundingRectangle
|
||||
print(f" ClassName : {wx.ClassName}")
|
||||
print(f" Title : {wx.Name}")
|
||||
print(f" HWND : {hwnd} (0x{hwnd:08X})")
|
||||
print(f" 屏幕位置 : ({rect.left}, {rect.top}) - ({rect.right}, {rect.bottom})")
|
||||
print(f" 窗口尺寸 : {rect.right - rect.left} x {rect.bottom - rect.top}")
|
||||
|
||||
# ── 2. UIA 控件树(2层快照)────────────────────────────────
|
||||
print("\n[2] UIA 控件树(深度=2):")
|
||||
print_uia_tree(wx, " ", max_depth=2)
|
||||
|
||||
# ── 3. Win32 子窗口枚举 ──────────────────────────────────────
|
||||
print("\n[3] Win32 子窗口句柄枚举(仅显示可见窗口):")
|
||||
children = enum_all_child_hwnds(hwnd)
|
||||
visible = [c for c in children if c['visible']]
|
||||
print(f" 共找到 {len(children)} 个子窗口句柄,其中 {len(visible)} 个可见。")
|
||||
print()
|
||||
|
||||
# 按 ClassName 分组统计
|
||||
class_count = {}
|
||||
for c in children:
|
||||
class_count[c['class']] = class_count.get(c['class'], 0) + 1
|
||||
print(" ClassName 分布统计:")
|
||||
for cls, cnt in sorted(class_count.items(), key=lambda x: -x[1]):
|
||||
print(f" {cnt:3d}x {cls}")
|
||||
|
||||
print()
|
||||
print(" 可见子窗口详细列表(前30个):")
|
||||
for i, c in enumerate(visible[:30]):
|
||||
title_info = f" Title='{c['title']}'" if c['title'] else ""
|
||||
print(f" [{i:02d}] HWND=0x{c['hwnd']:08X} Class='{c['class']}'{title_info} Rect={c['rect']}")
|
||||
|
||||
print()
|
||||
print("=" * 60)
|
||||
print("[提示] 请将以上输出完整截图/复制,发给 AI 进行分析。")
|
||||
print("=" * 60)
|
||||
Reference in New Issue
Block a user