# process_host **Repository Path**: chmodke/process_host ## Basic Information - **Project Name**: process_host - **Description**: Process Host 是一个 Windows 平台下的进程托管工具,采用守护进程 + 管理客户端的架构,支持将任意可执行程序作为 Windows 服务托管运行,提供自动重启、日志管理、独立配置等功能。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-12 - **Last Updated**: 2026-11-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Process Host [![Go Version](https://img.shields.io/badge/Go-1.20+-00ADD8?style=flat&logo=go)](https://go.dev/) [![Platform](https://img.shields.io/badge/Platform-Windows-0078D6?style=flat&logo=windows)](https://www.microsoft.com/windows) [![License](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) Process Host 是一个 Windows 平台下的进程托管工具,采用守护进程 + 管理客户端的架构,支持将任意可执行程序作为 Windows 服务托管运行,提供自动重启、日志管理、独立配置等功能。 > 注意:源代码均由DeepSeek生成,请勿直接插入工作交付件。 ## ✨ 特性 - **服务化运行**:守护进程作为 Windows 服务运行,开机自启,无需用户登录 - **多进程托管**:同时管理多个可执行程序,每个进程独立配置 - **自动重启**:进程崩溃后自动重启,可配置重启延迟 - **客户端分离**:守护进程与管理客户端独立,通过 TCP 通信 - **独立配置**:每个托管进程拥有独立的 YAML 配置文件 - **表格化展示**:CLI 以清晰的表格展示所有进程状态 - **定时任务**:`krond` 按 cron 表达式周期执行脚本,`kron` 通过本地 TCP 管理任务 - **跨平台潜力**:核心逻辑可扩展至 Linux/macOS ## 🏗️ 架构 ``` ┌─────────────────────────────────────────────────────────────┐ │ Windows Service (SCM) │ └─────────────────────────┬───────────────────────────────────┘ │ 管理 ▼ ┌─────────────────────────────────────────────────────────────┐ │ 守护进程 (daemon) │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │ │ │ API Server │ │ Manager │ │ 配置加载器 │ │ │ │ (TCP :9527) │ │ │ │ (processes/*.yaml) │ │ │ └──────┬──────┘ └──────┬──────┘ └─────────────────────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 托管进程 (Managed Processes) │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ │ │ java_app │ │ python │ │ nginx │ ... │ │ │ │ └──────────┘ └──────────┘ └──────────┘ │ │ │ └─────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ▲ │ TCP (JSON) │ ┌─────────────────────────┴───────────────────────────────────┐ │ 管理客户端 (cli) │ │ list | start | stop | restart | add | remove │ └─────────────────────────────────────────────────────────────┘ ``` ## 📦 安装 ### 从源码编译 ```bash # 克隆仓库 git clone https://gitee.com/chmodke/process_host.git cd process-host # 安装依赖 go mod download # 编译守护进程 cd phd go build -o phd.exe # 编译管理客户端 cd ../cli go build -o ph_ctl.exe # 编译调度进程与调度客户端 cd ../krond go build -o krond.exe cd ../kron go build -o kron.exe ``` 也可直接运行 `powershell -ExecutionPolicy Bypass -File build.ps1` 打包全部程序。 ### 安装 Windows 服务 以**管理员身份**运行命令提示符或 PowerShell: ```cmd # 创建服务 sc create ProcessHost binPath= "C:\path\to\phd.exe -config C:\path\to\daemon.yaml" start= auto # 启动服务 sc start ProcessHost ``` ## 🚀 快速开始 ### 1. 创建守护进程配置文件 `daemon.yaml`: ```yaml listen_addr: "127.0.0.1:9527" # API 监听地址 config_dir: "C:\\path\\to\\processes" # 托管进程配置目录,建议配置为绝对路径 log_dir: "C:\\path\\to\\logs" # 日志目录,建议配置为绝对路径 ``` > 目录重命名:托管进程配置目录已由 `configs/` 改为 `processes/`。升级时请同步修改 `daemon.yaml` 的 `config_dir`。 ### 2. 创建托管进程配置文件 在 `processes/` 目录下创建 `my_app.yaml`: ```yaml name: "my_app" enabled: true path: "C:\\path\\to\\your\\app.exe" args: ["-p", "8080"] workdir: "C:\\path\\to\\your" env: APP_ENV: "production" user: ".\\ph_test" password: "P@ssw0rd!" auto_restart: true restart_delay_sec: 10 ``` ### 3. 使用 CLI 管理 ```cmd # 查看所有进程状态 ph_ctl.exe list # 启动进程 ph_ctl.exe start my_app # 停止进程 ph_ctl.exe stop my_app # 注册新进程 ph_ctl.exe add C:\processes\another_app.yaml # 注销进程 ph_ctl.exe remove my_app ``` ## 📋 CLI 命令参考 | 命令 | 说明 | 示例 | |------|------|------| | `list` | 列出所有托管进程状态(表格形式) | `ph_ctl list` | | `status ` | 查看指定进程详细状态 | `ph_ctl status my_app` | | `start ` | 启动指定进程 | `ph_ctl start my_app` | | `stop ` | 停止指定进程 | `ph_ctl stop my_app` | | `restart ` | 重启指定进程 | `ph_ctl restart my_app` | | `add ` | 注册新进程(支持 YAML/JSON) | `ph_ctl add C:\my_app.yaml` | | `remove ` | 注销并删除进程配置 | `ph_ctl remove my_app` | **选项**: - `-addr string` - 守护进程地址(默认 `127.0.0.1:9527`) ## 📁 配置文件格式 ### 守护进程配置 (`daemon.yaml`) | 字段 | 类型 | 说明 | 默认值 | |------|------|------|--------| | `listen_addr` | string | API 服务监听地址 | `127.0.0.1:9527` | | `config_dir` | string | 托管进程配置目录 | `./processes` | | `log_dir` | string | 日志输出目录 | `./logs` | ### 托管进程配置 (`*.yaml`) | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `name` | string | 否 | 进程名称,默认使用文件名 | | `enabled` | bool | 否 | 是否随守护进程自动启动 | | `path` | string | **是** | 可执行文件绝对路径 | | `args` | []string | 否 | 启动参数 | | `workdir` | string | 否 | 工作目录 | | `env` | map[string]string | 否 | 环境变量 | | `user` | string | 否 | 运行账户:`DOMAIN\user`、`.\user` 或 `user@domain`;留空则继承守护进程账户 | | `password` | string | 否 | 账户密码(明文保存于配置文件) | | `auto_restart` | bool | 否 | 崩溃后是否自动重启 | | `restart_delay_sec` | int | 否 | 重启延迟(秒) | > **安全提示**:`password` 以明文保存在 `processes/*.yaml` 中,`add` 时也会以明文经 TCP 传输(默认仅监听 `127.0.0.1`)。请限制配置目录权限,例如: > `icacls processes /inheritance:r /grant:r "SYSTEM:(OI)(CI)F" "Administrators:(OI)(CI)F"` > **运行账户要求**:以指定用户运行依赖 `CreateProcessAsUser`,守护进程需以 LocalSystem 服务方式运行(或具备 `SeAssignPrimaryTokenPrivilege` / `SeIncreaseQuotaPrivilege`)。普通管理员前台调试会因缺少特权报错 1314。指定用户时环境变量由该用户的环境块生成,但不会加载该用户的 HKCU 注册表配置文件。 ## 🗂️ 项目结构 ``` process-host/ ├── go.mod ├── go.sum ├── README.md ├── phd/ # phd 守护进程 │ ├── main.go # 入口 │ ├── service.go # Windows 服务逻辑 │ ├── manager.go # 进程管理器 │ └── api.go # TCP API 服务 ├── cli/ │ └── main.go # ph_ctl 管理客户端 ├── krond/ # 定时任务调度进程 ├── kron/ │ └── main.go # 定时任务管理客户端 ├── internal/ │ ├── cron/ # 5 字段 cron 解析 │ └── winproc/ # 共享的进程启动 / run-as 逻辑 ├── protocol/ │ └── protocol.go # 共享通信协议 ├── processes/ # 托管进程配置目录 │ ├── java_app.yaml │ └── krond.yaml ├── jobs/ # 定时任务配置目录 │ └── example.yaml ├── daemon.yaml # 守护进程配置 ├── krond.yaml # 调度进程配置 └── build.ps1 # 构建与打包脚本 ``` ## 🔧 开发调试 ### 非服务模式运行守护进程 ```bash cd phd go run . -config daemon.yaml # 或直接运行编译后的程序 .\phd.exe -config daemon.yaml ``` 按 `Ctrl+C` 优雅退出。 ### 查看日志 日志文件位于 `log_dir` 配置的目录下: - `daemon.log` - 守护进程日志 - `<进程名>/process.log` - 各托管进程的启停与退出记录(不包含子进程 stdout/stderr) - `krond.log` - 调度进程日志(krond 的 `log_dir`) - `<任务名>/YYYY-MM-DD.log` - 定时任务每日执行日志,包含 stdout/stderr、退出码与耗时 ## ⏰ 定时任务(krond + kron) `krond` 是定时任务调度进程,由 phd 作为普通托管进程启动;`kron` 通过本地 TCP 直接管理 krond。 ``` phd (127.0.0.1:9527) ──托管── krond (127.0.0.1:9528) ◀── kron │ └── 按 cron 计划执行脚本 ``` ### 1. 由 phd 托管 krond 编辑 `processes/krond.yaml`,把 `path`、`args`、`workdir` 改成实际绝对路径,将 `enabled` 改为 `true`,重启 phd(或先 `ph_ctl add processes/krond.yaml` 再启动)。建议设置 `workdir`,这样 `krond.yaml` 中的相对 `jobs_dir` 才能正确解析。 `krond.yaml`: ```yaml listen_addr: "127.0.0.1:9528" jobs_dir: "jobs" # 任务配置目录,相对 krond 工作目录 log_dir: "C:\\path\\to\\logs\\kron" # 省略则默认 C:\ProgramData\ProcessHost\logs\kron ``` ### 2. 任务配置 任务统一存放在 `jobs/` 目录(`jobs_dir`),也可通过 `kron add` 注册。示例 `jobs/backup.yaml`: ```yaml name: "backup" enabled: true schedule: "0 2 * * *" # 每天 02:00 path: "C:\\Windows\\System32\\cmd.exe" # 必需:显式解释器 args: ["/c", "C:\\scripts\\backup.bat"] # 脚本路径放在参数中 workdir: "C:\\scripts" env: BACKUP_DIR: "D:\\backup" # user: ".\\svcuser" # 可选,语义与 phd 一致 # password: "secret" ``` - `schedule` 为标准 5 字段 cron(分 时 日 月 周),支持 `*`、`a-b`、`*/n`、`a-b/n`、逗号列举;最小粒度 1 分钟,按本地时间执行。 - 脚本必须显式指定解释器(`cmd.exe /c`、`powershell.exe -NoProfile -File` 等),不会自动包装 `.bat`/`.ps1`。 - `auto_restart` / `restart_delay_sec` 对定时任务无效。 - 任务名称允许中文,但不能包含 `\ / : * ? " < > |`,不能是 Windows 保留名(CON、COM1 等),长度不超过 64 字符。 ### 3. kron 命令 | 命令 | 说明 | |------|------| | `kron list` | 列出全部任务及下次/上次执行状态 | | `kron show ` | 查看任务配置与运行状态 | | `kron add ` | 注册任务(支持 YAML/JSON) | | `kron remove ` | 删除任务配置,并终止正在运行的实例 | | `kron enable ` | 启用调度并持久化 | | `kron disable ` | 禁用调度(不中断正在运行的实例) | `kron` 的 `-addr`(默认 `127.0.0.1:9528`)需放在动作之前,例如 `kron -addr 127.0.0.1:9528 list`。 ### 4. 调度语义与执行日志 - 同一任务上次执行未结束时,本次触发**跳过**并在 `krond.log` 记录告警。 - krond 停机期间错过的触发**不补跑**。 - 运行时状态(下次执行、上次退出码、耗时等)仅保存在内存,krond 重启后清空;执行历史以日志文件为准。 - 每个任务每天一个日志:`/<任务名>/YYYY-MM-DD.log`,包含开始/结束标记、stdout/stderr、退出码与耗时。 - 修改 `jobs/*.yaml` 后需重启 krond;运行期变更请使用 `kron`。 - 密码明文保存在任务 YAML,并明文经本地 TCP 传输。 - phd 停止 krond 时是硬终止,正在执行的脚本子进程可能残留。 ## ❓ 常见问题 ### Q: 服务启动失败,报错 1053? A: 通常是配置文件路径问题或依赖缺失。请检查: 1. `daemon.yaml` 中的路径是否正确 2. 托管进程的 `path` 是否使用绝对路径 3. 工作目录是否有写入权限 ### Q: CLI 无法连接守护进程? A: 确保: 1. 守护进程服务已启动 2. 防火墙允许本地 9527 端口通信 3. `-addr` 参数与守护进程配置一致 ### Q: 进程启动后立即退出? A: 查看守护进程日志,通常是因为: 1. 可执行文件路径错误 2. 缺少依赖的 DLL 或环境变量 3. 工作目录权限不足 ## 🤝 贡献 欢迎提交 Issue 和 Pull Request! ## 📄 许可证 MIT License - 详见 [LICENSE](LICENSE) 文件。