Files
dsh_ai1net_server/归档/技能-退役-20261001/workbuddy-session-forensics/scripts/proc-parent.py
T
admin c1b5e4d966 chore(工作区): 全量入库 + 补齐 .gitignore(以工作区为准)
- 变更规模:新增 514 / 修改 62 / 重命名 155 / 删除 4(归档重组与文档轮次)
- .gitignore 修:`归档/**/db-cwd归一-备份-*/` —— 原规则写绝对层级(归档/db-cwd归一-…),
  目录搬进 归档/配置与备份/ 后**静默失效**,43 MB 的 DB 备份又变成未跟踪
- .gitignore 补:嵌套 git 内部数据(归档/内嵌git-20261008/、归档/skills-git-旧线-20261007/dotgit-原样移出/)
- .gitignore 补:运行态与部署副本(.workbuddy/collab/、.workbuddy/tools/、.workbuddy/.load-pending、.workbuddy/tmp-*)
- .gitignore 补:备份件(*.bak-*)
- 未跟踪文件从 2190 降到 890(其余为 归档/ 归档件与 .workbuddy/memory/ 知识文件,按口径入库)
2026-10-10 23:13:22 +08:00

76 lines
2.3 KiB
Python

# -*- coding: utf-8 -*-
"""proc-parent —— 打印进程父链(纯 stdlib ctypes,⛔ 不依赖 psutil)。
用途(配合 SKILL.md §2j):判断某个进程**是不是某个 WorkBuddy 会话的后台任务**。
python proc-parent.py <pid> [pid2 ...]
读数:
· 链上出现 `… ← sandbox-cli.exe ← WorkBuddy.exe` ⇒ 是会话/宿主托管的**后台任务**
· 链上出现 `services.exe` / `svchost.exe` / `explorer.exe` ⇒ 是**独立进程**(计划任务/启动文件夹/手工起)
⚠️ 本脚本只读(CreateToolhelp32Snapshot)—— ⛔ 不结束、不修改任何进程。
"""
import ctypes
import ctypes.wintypes as wt
import sys
TH32CS_SNAPPROCESS = 0x00000002
MAX_PATH = 260
class PROCESSENTRY32(ctypes.Structure):
_fields_ = [
("dwSize", wt.DWORD),
("cntUsage", wt.DWORD),
("th32ProcessID", wt.DWORD),
("th32DefaultHeapID", ctypes.POINTER(ctypes.c_ulong)),
("th32ModuleID", wt.DWORD),
("cntThreads", wt.DWORD),
("th32ParentProcessID", wt.DWORD),
("pcPriClassBase", ctypes.c_long),
("dwFlags", wt.DWORD),
("szExeFile", ctypes.c_char * MAX_PATH),
]
def snapshot():
k = ctypes.windll.kernel32
h = k.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
if h == -1:
return {}
pe = PROCESSENTRY32()
pe.dwSize = ctypes.sizeof(PROCESSENTRY32)
out = {}
ok = k.Process32First(h, ctypes.byref(pe))
while ok:
out[pe.th32ProcessID] = (pe.th32ParentProcessID, pe.szExeFile.decode("mbcs", "replace"))
ok = k.Process32Next(h, ctypes.byref(pe))
k.CloseHandle(h)
return out
def main():
pids = [a for a in sys.argv[1:] if a.isdigit()]
if not pids:
print("用法: python proc-parent.py <pid> [pid2 ...]")
return 1
procs = snapshot()
for arg in pids:
pid = int(arg)
print("=== pid %d ===" % pid)
seen, cur = set(), pid
while cur and cur in procs and cur not in seen:
seen.add(cur)
ppid, name = procs[cur]
print(" %-8d %-22s ppid=%d" % (cur, name, ppid))
cur = ppid
if cur and cur not in procs:
print(" %-8d (已退出) <- 链在此断" % cur)
print()
return 0
if __name__ == "__main__":
sys.exit(main())