Files
ykxmz/_build/desktop_state.py
xmz7891 d5a1943d1f 加两个运维辅助脚本
_build/watch_stability.py   连续打公网统计可用率(验证隧道加固效果)
  _build/desktop_state.py     列出当前可见窗口 + 输入桌面名
                              (排查"桌面消失/一片蓝"这类问题用)

这两个是查 2.1.1 / 2.1.2 那两个问题时写的,以后还会用到。

顺便记一笔当时的排查结论(2026-10-08):
用户报"桌面消失、一片蓝、有个蓝色窗口",查下来:
    * 输入桌面是 Default(正常),explorer 在跑
    * 那 9 个"全屏窗口"全是 Windows 自己的 UWP 组件
      (开始菜单 / 搜索 / 锁屏 / 输入法),程序枚举时会误报全屏
    * 真正开着的是「设置」App 和任务管理器
    * 自启项里没有 ykxmz,也没有残留的隐藏桌面或测试进程
    * 18:42:41 有一次**非正常关机**(Kernel-Power 41 / EventLog 6008),
      19:58 重启。没有任何蓝屏或硬件错误记录 ——
      最符合"掉电或硬挂",不是软件崩溃。
2026-10-08 20:08:16 +08:00

121 lines
4.2 KiB
Python

# -*- coding: utf-8 -*-
r'''看当前桌面/窗口的真实状态 —— 诊断"桌面消失、一片蓝"。
用户报:"我现在桌面消失了,电脑一片蓝,然后还有个蓝色的窗口"。
已知:
18:42:41 机器异常关机(Kernel-Power 41 / EventLog 6008,无蓝屏记录)
19:58:23 重新启动
20:01:37 explorer 起来
自启项里没有 ykxmz,当前也没有 ykxmz 在跑
要查的是:现在屏幕上到底有什么、是不是有全屏窗口盖住了桌面。
'''
from __future__ import annotations
import ctypes
import ctypes.wintypes as wt
import subprocess
user32 = ctypes.WinDLL("user32", use_last_error=True)
EnumWindows = user32.EnumWindows
EnumWindows.argtypes = [ctypes.WINFUNCTYPE(wt.BOOL, wt.HWND, wt.LPARAM),
wt.LPARAM]
class RECT(ctypes.Structure):
_fields_ = [("left", wt.LONG), ("top", wt.LONG),
("right", wt.LONG), ("bottom", wt.LONG)]
def windows() -> list:
out = []
def cb(hwnd, _lp):
if not user32.IsWindowVisible(hwnd):
return True
title = ctypes.create_unicode_buffer(512)
user32.GetWindowTextW(hwnd, title, 512)
cls = ctypes.create_unicode_buffer(256)
user32.GetClassNameW(hwnd, cls, 256)
r = RECT()
user32.GetWindowRect(hwnd, ctypes.byref(r))
pid = wt.DWORD()
user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid))
w, h = r.right - r.left, r.bottom - r.top
if w > 80 and h > 80:
out.append({"hwnd": hwnd, "title": title.value, "cls": cls.value,
"pid": pid.value, "w": w, "h": h,
"x": r.left, "y": r.top})
return True
EnumWindows(ctypes.WINFUNCTYPE(wt.BOOL, wt.HWND, wt.LPARAM)(cb), 0)
return out
def proc_name(pid: int) -> str:
try:
r = subprocess.run(
["powershell", "-NoProfile", "-Command",
"(Get-Process -Id %d -EA SilentlyContinue).ProcessName" % pid],
capture_output=True, text=True, timeout=8)
return (r.stdout or "").strip() or "?"
except Exception: # noqa: BLE001
return "?"
def main() -> int:
sw = user32.GetSystemMetrics(0)
sh = user32.GetSystemMetrics(1)
print(" 屏幕: %d x %d" % (sw, sh))
print(" 当前输入桌面: %s" % _desktop_name())
print()
ws = windows()
ws.sort(key=lambda w: w["w"] * w["h"], reverse=True)
print(" 可见窗口 %d 个(按面积排序,前 20):" % len(ws))
for w in ws[:20]:
full = w["w"] >= sw - 4 and w["h"] >= sh - 4
pn = proc_name(w["pid"])
print(" %s %-14s pid=%-6d %dx%d @(%d,%d)"
% ("★全屏" if full else " ", pn, w["pid"],
w["w"], w["h"], w["x"], w["y"]))
print(" 类=%-22s 标题=%r" % (w["cls"][:22], w["title"][:60]))
print()
fulls = [w for w in ws if w["w"] >= sw - 4 and w["h"] >= sh - 4]
if fulls:
print(" ⚠ 有 %d 个全屏窗口 —— 下面这些就是盖住桌面的嫌疑:" % len(fulls))
for w in fulls:
print(" pid=%d (%s) 类=%s 标题=%r"
% (w["pid"], proc_name(w["pid"]), w["cls"], w["title"][:50]))
else:
print(" ✓ 没有全屏窗口盖着")
print()
ex = subprocess.run(["powershell", "-NoProfile", "-Command",
"Get-Process explorer -EA SilentlyContinue | "
"Select-Object -First 1 -ExpandProperty Id"],
capture_output=True, text=True, timeout=10)
print(" explorer PID: %s" % ((ex.stdout or "").strip() or "**没在跑**"))
return 0
def _desktop_name() -> str:
"""当前输入桌面的名字。Default = 正常,Winlogon = 锁屏。"""
h = user32.OpenInputDesktop(0, False, 0x0001)
if not h:
return "(拿不到 —— 可能锁屏或没有交互桌面)"
try:
sb = ctypes.create_unicode_buffer(256)
need = wt.DWORD()
ok = user32.GetUserObjectInformationW(h, 2, sb, 512,
ctypes.byref(need))
return sb.value if ok else "(拿不到名字)"
finally:
user32.CloseDesktop(h)
if __name__ == "__main__":
import sys
sys.exit(main())