pyinstaller-win-gui

SKILL开发
开发 未标注权限 许可证不明确
安装这个技能

把 Python 脚本打包成 Windows 单文件窗口 exe,并让它 7×24 稳定常驻:单实例互斥、防多实例互杀、令牌 BOM 处理、开机自启、关窗最小化保活。沉淀自 SCADA 监控管理器(MonitorManager)真实踩坑。

一句话选型结论

按资料字段整理

pyinstaller-win-gui是开发类的 Agent Skill,安装方式未标注,权限级别未标注,许可证不明确,有可直接复制的安装命令。技能本质是给模型读的说明书,效果取决于模型与客户端;装完先用一个小任务验证,再放进正式流程。

分类开发 安装方式未标注 权限级别未标注权限 许可证许可证不明确
累计安装 未标注 本周 未标注
GitHub 星标 未标注 仓库 未标注
下载量 未标注 技能市场下载数
权限级别 未标注权限 安装前请确认风险范围
许可证 许可证不明确 未说明

安装

未标注
在支持 Skills 的客户端里执行,装完问一句「你有哪些技能」验证
skillhub install user_9aa69e66/pyinstaller-win-gui
  1. 1
    确认客户端支持

    确认你的客户端支持 Skills(Claude、Codex、Cursor 等),并升级到较新的版本。

  2. 2
    拿到技能文件

    执行上面的命令安装;也可以把仓库里的 SKILL.md 手动放进客户端的 skills 目录。

  3. 3
    刷新技能列表

    重新打开客户端,或刷新技能列表,让新放进来的技能被加载。

  4. 4
    验证是否生效

    问一句「你有哪些技能」,确认列表里出现它,再拿一个小任务试跑。

技能档案

开发
字段来自技能仓库与公开索引,中文说明由本站标注
作者 / 维护方user_9aa69e66仓库 未标注 · 版本 未标注
宿主客户端未标注技能可被这些客户端加载
安装方式未标注安装包 community
权限级别未标注权限安装前请确认风险范围
许可证未说明许可证不明确,商用前请自行确认条款
仓库可用性available技能仓库当前是否可访问
最近核验未标注上游最后核验时间 · 数据更新 1791681575
正文体量9.5 KBSKILL.md 原文大小,越大说明说明书写得越细

典型使用场景

3 类
按分类整理的常见用法,具体以 SKILL.md 为准
写代码与改 bug

按需求补代码、定位并修掉报错。

读仓库与生成改动

让模型读懂项目结构,再给出可落地的改动。

跑测试与排查故障

按现象排查问题,补测试用例并复跑。

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 有可直接复制的安装命令,不用自己翻文档找入口。

先想清楚的地方

  • 没有标注权限级别,实际能做什么要装好后确认。
  • 许可证不明确,商用或二次分发前先到仓库确认条款。
  • 没有做站内核验,内容以作者仓库为准。
  • 技能只是说明书,实际效果取决于模型与客户端,装完先用小任务试一遍。

更适合

  • 需要在开发场景里给模型补一套做法的人。
  • 愿意先读一遍 SKILL.md、确认它会让模型做什么的人。

不太适合

  • 对许可证要求很严、必须明确可商用的人。
  • 只想装完就自动变强、不打算看说明书的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
技能权限级别安装方式累计安装宿主客户端安装命令
pyinstaller-win-gui当前 未标注权限 未标注 未标注 未标注 有
技能审查员 浏览器控制 ClawHub 市场 877.9 万 OpenClaw 有
Vercel React 最佳实践 浏览器控制 GitHub 仓库 849.1 万 Codex、Claude、Cursor 有
GitHub 代码协作 联网访问 ClawHub 市场 763.3 万 OpenClaw 有
网页设计指南 联网访问 GitHub 仓库 668.6 万 Codex、Claude、Cursor 有
本体论 只读 ClawHub 市场 663.7 万 OpenClaw 有

SKILL.md 全文

9.5 KB
模型实际读到的说明书原文,来自技能仓库

Windows 单文件 GUI 守护工具打包与稳定运行

把"一个 Python 服务 + 一个看门狗"做成一个双击即用的单文件窗口 exe,并做到开机自启、关窗不丢保活、多实例不互杀。本技能是 SCADA 监控管理器 MonitorManager.exe 实战沉淀,每段都来自真实踩坑,不要凭空发挥。

0. 设计与包装原则(先读)

  • 纯标准库:GUI 用 tkinter,保活用 threading + subprocess,配置读写用内置 json/winreg。不引入第三方依赖 → 打包体积小、运行稳。
  • 独立打包 venv:新建一个 venv 专门装 pyinstaller,不要污染被守护服务的运行环境。
  • 职责单一:管理器只负责"启动/停止/看护"既有的服务脚本(如 alarm_monitor.py),升级服务代码无需改动管理器。
  • 状态以真实进程为准,不要只靠内存布尔开关(这是"停止系统误报未运行"的根因,见步骤 7)。

1. 单文件窗口打包

# 在独立打包 venv 里
python -m venv C:\Users\yanya\.workbuddy\binaries\python\envs\builder
builder\Scripts\pip install pyinstaller
builder\Scripts\pyinstaller.exe --noconfirm --onefile --windowed --name MonitorManager monitor_manager.py
  • --windowed:不弹控制台黑框;--onefile:产出单个 exe。
  • ⚠️ PyInstaller 单文件运行时会有"引导外壳进程 + 真正应用进程"两个 exe 进程,应用进程持有单实例锁。任务管理器看到 2 个同名进程是正常的,不是 Bug。

2. 单实例互斥(防止重复拉起打架)

用"占用一个本地 TCP 端口"当互斥锁——简单可靠,比文件锁干净。

import socket
INSTANCE_PORT = 58099

def ensure_single_instance():
    """占用本地端口作为单实例锁;返回 False 表示已有实例在运行。"""
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 0)
        sock.bind(("127.0.0.1", INSTANCE_PORT))
        sock.listen(1)
        globals()["_instance_sock"] = sock   # 挂全局防 GC 释放
        return True
    except OSError:
        return False

# 在 main() 最前面:
def main():
    if not ensure_single_instance():
        # 开机自启(--minimized)场景:静默退出,避免弹窗干扰
        if "--minimized" not in sys.argv:
            try:
                r = tk.Tk(); r.withdraw()
                messagebox.showinfo("提示", "监测管理器已在运行,无需重复启动。")
                r.destroy()
            except Exception:
                pass
        return
    ...
  • 重复双击 / 开机自启第二份会被拦截,不会并存多套保活。

3. 防多实例互杀(保活核心坑)

致命坑:保活逻辑里若每次都 taskkill /F /IM cloudflared.exe 先杀"全部"同类进程再重启,一旦有多个 Manager 实例并存,它们会互相杀对方的进程 → 隧道重启风暴。
正确做法:保活前先 detect_running() 看真实状态,只在"进程缺失 / 公网不可达且冷却已过"时才重启;绝不一上来就无脑 kill 全部。

import subprocess, time

def http_ok(url, timeout=8):
    try:
        r = subprocess.run(["powershell", "-NoProfile", "-Command",
            "Invoke-WebRequest -Uri '%s' -UseBasicParsing -TimeoutSec %d" % (url, timeout)],
            capture_output=True, creationflags=0x08000000, timeout=timeout+5)
        return r.returncode == 0
    except Exception:
        return False

def detect_running():
    """以真实进程为准:(python_ok, tunnel_ok)。"""
    try:
        out = subprocess.check_output(
            ['wmic', 'process', 'where', "name='python.exe'", 'get', 'CommandLine', '/value'],
            creationflags=0x08000000, timeout=15).decode('gbk', 'ignore')
        py = 'alarm_monitor.py' in out
    except Exception:
        py = False
    try:
        t = subprocess.check_output(['tasklist', '/FI', "IMAGENAME eq cloudflared.exe"],
                                    creationflags=0x08000000, timeout=15).decode('gbk', 'ignore')
        cf = 'cloudflared.exe' in t
    except Exception:
        cf = False
    return py, cf

# 保活线程里:
CF_RESTART_COOLDOWN = 30
def keepalive_loop(self):
    while True:
        time.sleep(20)
        py_ok, cf_ok = detect_running()
        public_ok = http_ok(self.cfg["PUBLIC_URL"])
        # 隧道:进程在且公网通 -> 不动;否则才重启(且距上次启动 > 冷却)
        if (not cf_ok) or (cf_ok and not public_ok and (time.time() - self.last_cf_start) > CF_RESTART_COOLDOWN):
            self.restart_tunnel()   # 只重启隧道,不杀 python 服务
  • 配套技能 win-powershell-envfix 处理 restart_tunnel 里 Start-Process 崩溃的坑(PATH 双键)。

4. 令牌 / 配置 BOM 处理(隐蔽认证坑)

真实事故:隧道令牌文件带 UTF-8 BOM(EF BB BF)。用 open(encoding='utf-8') 读取会把 3 个不可见字节混进令牌 → Cloudflare 报 Provided Tunnel token is not valid → 隧道启动即退出 → 公网 502/530 抖动。
修复:一律用 utf-8-sig 自动去 BOM。

# 读令牌 / 读配置文件,统一 utf-8-sig
with open(token_file, "r", encoding="utf-8-sig") as f:
    tok = f.read().strip()
with open(config_file, "r", encoding="utf-8-sig") as f:
    cfg = json.load(f)
  • 判断文件是否带 BOM(PowerShell):$b=(gc file -Encoding Byte)[0..2] 看是否 0xEF,0xBB,0xBF。

5. 开机自启(注册表 Run)

import winreg
def set_autostart(enable, exe_path):
    key = winreg.OpenSubKey(winreg.HKEY_CURRENT_USER,
        r"Software\Microsoft\Windows\CurrentVersion\Run", 0, winreg.KEY_SET_VALUE)
    if enable:
        val = '"%s" --minimized' % exe_path   # --minimized 让开机自启后台跑
        key.SetValue("SCADAMonitorManager", val)
    else:
        try: key.DeleteValue("SCADAMonitorManager")
        except OSError: pass
    key.Close()
  • 用 HKEY_CURRENT_USER(无需管理员权限)。值带 --minimized 让开机自启不弹窗。

6. 关窗口 = 最小化(保活继续)

默认点 × 会销毁窗口、保活线程跟着没了。改成最小化到任务栏:

self.root.protocol("WM_DELETE_WINDOW", self.on_minimize)
def on_minimize(self):
    self.root.iconify()   # 仅最小化,保活线程继续运行
  • 单独设「退出管理器」按钮做真正退出(退出后服务仍在跑,但保活暂停,重开即恢复);「停止系统」按钮才彻底停服务。

7. 状态显示用真实检测(修复"停止系统误报未运行")

真实事故:管理器用内存布尔 self.running 判断是否在跑。管理器被重启/多实例后,running 与实际进程脱节 → 点「停止系统」走 if not self.running 分支直接报"系统未运行"、根本没杀进程。
修复:启动时用 detect_running() 认领既有进程、同步 running 与按钮态;stop_system 闸门改为"内存标志未运行 且 真实进程都不在"才报未运行,否则按名称清理。

def stop_system(self):
    py_ok, cf_ok = detect_running()
    if (not self.running) and (not py_ok) and (not cf_ok):
        self.write_log("系统未运行。")
        return
    self.running = False
    # 按名称清理真实进程(见 win-powershell-envfix 的精确清理法)
    ...

8. 质量反例(不要这样写)

  • ❌ 保活先 taskkill /F /IM cloudflared.exe 无脑杀全部 → 多实例互杀风暴。
  • ❌ 用 open(encoding='utf-8') 读令牌文件 → BOM 字节混入导致认证失败。
  • ❌ 只靠内存 running 布尔判断状态 → 重启/多实例后状态脱节、停止失效。
  • ❌ 用 netstat 解析 LISTENING 的 PID 来定位进程 → 不可靠(曾误判成 8 误杀主进程)。改用 Get-CimInstance 按命令行匹配(见配套技能)。
  • ❌ 在运行服务的同一个 venv 里装 pyinstaller → 污染运行环境。

9. 完成前检查清单

  • [ ] 用独立 venv 的 pyinstaller 打包,--onefile --windowed
  • [ ] 单实例互斥已加(重复启动被拦,开机自启静默退出不弹窗)
  • [ ] 保活逻辑用 detect_running() 真实状态,无"无脑 kill 全部"
  • [ ] 读令牌/配置统一 utf-8-sig
  • [ ] 开机自启写入 HKCU\...\Run(值带 --minimized)
  • [ ] 关窗口 = 最小化(保活继续),有独立"退出/停止"按钮
  • [ ] 状态显示基于真实进程检测,停止按钮能真正停掉
  • [ ] 实测:启停正常、公网可达、模拟杀隧道后自动拉起、重启整机验证开机自启

10. 参考

  • 配套技能 win-powershell-envfix:本技能"启动隧道/子进程"与"精确清理进程"依赖它的 PATH 折叠与进程清理法。
  • 实际成品参考:D:\工作空间\monitor_manager.py(本文所有片段的出处)。

常见问题

5 问
答案由本站依据条目字段整理
pyinstaller-win-gui怎么安装?

在支持 Skills 的客户端里执行:skillhub install user_9aa69e66/pyinstaller-win-gui。安装方式为未标注。装完刷新技能列表或重开客户端。

pyinstaller-win-gui支持哪些客户端?

资料没有标注宿主客户端,但只要客户端支持 Skills(Claude、Codex、Cursor 等),一般都能加载。

pyinstaller-win-gui权限高吗,安全吗?

权限级别为未标注权限。安装前先看它会读取或写入哪些内容。

pyinstaller-win-gui收费吗?

本站不代收费用,也没有标注具体价格。是否收费取决于技能本身和所用的模型或客户端,正式使用前按作者说明确认。

pyinstaller-win-gui用什么许可证?

许可证标注为 未说明(许可证不明确)。商用或二次分发前请到仓库确认条款原文。

热门专题

按场景挑技能
全部专题 →

技能内容以作者仓库为准;分类、权限级别与许可证状态的中文说明为中文整理,最近核验 未标注。