Windows Local Web Autostart(本地 Web 应用启动治理)
Overview
本技能用于治理 Windows 单机环境下、以 Python 本地 server 托管的 Web 应用(含纯前端 SPA)的
"启动可靠性"全链路:诊断多实例进程冲突 → 幂等清理旧残留 → 拉起一组干净的看门狗+server →
配置开机自启与兜底自愈。目标是一劳永逸消除"启动失败/端口被抢/重启不拉起"三类问题。
Privacy & Data Safety(隐私与数据安全 · 强制)
- 本技能完全通用,与任何具体业务(股票/财务/个人数据)无关。
- 所有脚本与文档中禁止出现真实路径、真实 PID、真实账号、真实持仓/股票代码、个人姓名。
- 示例一律使用占位数据:应用目录用
E:\Apps\local-dashboard,旧路径用D:\legacy-app-backup,
端口用<PORT>(演示常用 8080),进程用<PID>。 - 若用户要求清理的"旧路径"指向其真实业务目录,执行删除前必须用 AskUserQuestion 二次确认范围,
严禁把"正在使用的客户端本体"误判为"旧残留"而删除(见下"踩坑")。
When To Use(触发场景)
- "localhost 打不开 / 8080 连不上 / ERR_CONNECTION_REFUSED"
- "启动失败、端口被占用、多个 server 抢端口"
- "看门狗/守护进程冲突、重复拉起"
- "重启电脑后应用不自动启动"
- "彻底清理旧的启动配置、计划任务、旧目录残留"
- 用户提交截图显示进程列表里有多个同名 python/pythonw,或计划任务里有重复项
Scope(功能边界)
IN(本技能覆盖):
- Windows 10/11 单机;Python pythonw.exe / python.exe 进程。
- 同端口多实例冲突的诊断与收敛。
- 计划任务(schtasks)的注册/删除(onstart 开机触发、minute 周期兜底)。
- 旧路径文件递归删除(仅用户显式传入的路径,不扫全盘)。
- 重启一组干净的看门狗+server 并 HTTP 探活验证。
OUT(不在本技能范围,需另写):
- Linux / macOS(语法不同,无 schtasks)。
- 容器编排、远程多机部署。
- 真正的 Windows Service 注册(需 sc.exe / New-Service,本技能只用到 schtasks)。
- 业务代码逻辑修改、前端功能开发。
Inputs / Outputs(输入输出规范)
Inputs(由用户或上下文提供,缺省用占位/默认值):
- $AppName:应用名,用于计划任务前缀与日志标识(默认 LocalWebApp)。
- $AppHome:应用根目录(含 server/watchdog 脚本),如 E:\Apps\local-dashboard。
- $Port:服务端口(默认 8080)。
- $Launcher:看门狗启动器路径(.bat 或 .vbs,无窗口启动用 .vbs)。
- $OldPaths:要清理的旧路径数组(可选,如 @('D:\legacy-app-backup'))。
- $ProcessMatch:命令行匹配串数组(默认 @('watchdog.py','server.py'))。
Outputs:
- 状态快照:python 进程数/列表、<PORT> 探活结果、计划任务清单、旧路径存在性。
- 清理摘要:DELETED (n) / SKIPPED (n) 清单,每项含类型+标识。
- 验证结果:http://127.0.0.1:<PORT>/<probe> 的 HTTP 状态码(成功为 200)。
Workflow
Step 0 — 只读侦察(diagnose.ps1)
先列出真实状态,不改动任何东西。运行:
powershell -ExecutionPolicy Bypass -File "<SKILL>/scripts/diagnose.ps1" `
-AppName LocalWebApp -ProcessMatch @('watchdog.py','server.py') -Port 8080 -TaskPrefix LocalWebApp
判读:
- python 进程 > 2(1 看门狗 + 1 server 才是健康态)→ 存在冲突,进入 Step 1。
- <PORT> 探活 DOWN → server 没起来或端口被抢。
- 计划任务有重复/旧项 → 进入 Step 1 一并清。
Step 1 — 编写/复用幂等清理脚本(cleanup_startup.ps1)
脚本已内置在 scripts/。核心特性:
- 默认 dry-run:只列 [targets],不删任何东西。
- 加 -Apply 才真删。
- 先列后删 + 摘要:结尾输出 DELETED / SKIPPED。
- 幂等:所有操作先判断存在性,重复执行无残留即全 SKIP,不报错。
- 进程:用 Get-CimInstance Win32_Process 匹配命令行含 $ProcessMatch 的 python 进程,Stop-Process。
- 任务:删 $TaskPrefix* 计划任务(schtasks /delete)。
- 旧路径:Remove-Item -Recurse -Force(仅 $OldPaths 显式传入的路径)。
- 陈旧服务脚本:可选 -RemoveStaleServiceScript 删项目内指定名称的旧安装脚本。
Step 2 — 执行清理(预览 → 真删)
# 预览
powershell -ExecutionPolicy Bypass -File "<SKILL>/scripts/cleanup_startup.ps1" `
-AppName LocalWebApp -OldPaths @('D:\legacy-app-backup') -RemoveScheduledTasks -RemoveStaleServiceScript
# 确认 targets 无误后真删
powershell -ExecutionPolicy Bypass -File "<SKILL>/scripts/cleanup_startup.ps1" `
-AppName LocalWebApp -OldPaths @('D:\legacy-app-backup') -RemoveScheduledTasks -RemoveStaleServiceScript -Apply
Step 3 — 拉起一组干净的看门狗+server 并验证
清理完进程后 server 会暂时 DOWN(脚本只清不启)。立即拉起一组新进程:
$pyw = (Get-Command pythonw).Source # 或显式 pythonw 路径
Set-Location $AppHome
Start-Process -FilePath $pyw -ArgumentList 'watchdog.py',$Port -WindowStyle Hidden -WorkingDirectory $AppHome
Start-Sleep -Seconds 4
# 验证
Invoke-WebRequest -Uri "http://127.0.0.1:$Port/<probe>" -UseBasicParsing -TimeoutSec 3
预期:python 进程 = 2(1 看门狗 + 1 server),HTTP 200。
Step 4 — 配置开机自启 + 兜底自愈(install_autostart.ps1)
注册两个 SYSTEM 计划任务,实现"重启自动拉起 + 进程死了 5 分钟内自愈":
powershell -ExecutionPolicy Bypass -File "<SKILL>/scripts/install_autostart.ps1" `
-AppName LocalWebApp -Launcher "E:\Apps\local-dashboard\launch_watchdog.vbs" -Port 8080
脚本会:
1. StockSystemServer(onstart 触发器,系统启动即拉起,无需登录)+ SYSTEM + Hidden。
2. StockSystemServer_Watchdog(每 5 分钟,防看门狗自己也死)+ SYSTEM + Hidden。
3. 用 /f 覆盖,幂等可重复跑。
调用方式小结
| 动作 | 命令 |
|---|---|
| 诊断 | diagnose.ps1 -AppName ... -Port ... |
| 预览清理 | cleanup_startup.ps1 ...(无 -Apply) |
| 执行清理 | cleanup_startup.ps1 ... -Apply |
| 重启验证 | Start-Process pythonw watchdog.py + Invoke-WebRequest |
| 配自启 | install_autostart.ps1 -AppName ... -Launcher ... |
踩坑 / 注意
- 勿把"正在使用的客户端本体"当旧残留删:侦察
OldPaths时若发现目录含Uninstall*.exe、
Electron 运行时、主程序 exe,立即排除并追问用户,绝不递归删除。 - bat 必须纯 ASCII:CMD 默认 GBK 解码无 BOM 的 UTF-8 中文会把
::注释乱码成"未识别命令"。
所有.bat/.ps1字符串与注释一律英文。 - PowerShell 工具不捕获 Write-Host:脚本输出用
6>&1 | Out-File或Write-Output落盘读取。 - 沙箱/受限环境:文件删除类操作可能被"安全删除"策略拦截(fail-closed)。此时进程/计划任务删除
仍可用,文件删除需用户在自己机器以管理员运行完成。 - 清理脚本杀进程但不重启:杀完 8080 会短暂 DOWN,必须走 Step 3 拉起新进程,否则浏览器仍打不开。
- SYSTEM 账户跑 server:路径须全绝对、绑定
127.0.0.1:<PORT>(跨会话可达)、写日志文件有权限。