
简介NSSM 2.24-101-g897c7ad 是基于特定 Git 提交构建的 Windows 服务封装工具面向需要将任意可执行程序注册为系统后台服务的运维与开发人员相比 Windows 自带的 srvany它更易用集成错误日志、环境变量、启动参数等配置能力特别适合需要开机自启、无人值守运行的业务进程。压缩包共 40 个文件、约 376KB包含 15 个头文件和 14 个 C 源文件组成的完整工程源码同时提供 win32/win64 两版可直接运行的 exe、Visual Studio 工程文件以及 .rc/.mc/.ico 等资源与 Readme、ChangeLog 文档既能在命令行中快速完成服务安装、配置和状态查看也能基于源码二次编译、定制或学习内部实现。核心源码按服务注册、注册表读写、环境变量注入、进程管理、钩子处理等模块拆分通过阅读可以理解 NSSM 如何把普通 exe 包装成系统服务、如何与 Windows 服务控制管理器交互以及恢复策略和服务依赖的具体配置方式。已有 428 人学习下载适合想深入掌握 Windows 服务编程与后台服务管理的开发者。1. nssm-2.24-101-g897c7ad 是什么一个比 2.24 更值得用的 Windows 服务管理器快照NSSM 可能是 Windows 运维圈里最被低估的一个工具。它能把任意 exe、bat、Python 脚本注册成系统服务服务挂了自动拉起日志自动轮转比任务计划程序好使太多。而 nssm-2.24-101-g897c7ad 这个版本号光是读出来就包含不少信息主版本 2.24后面跟了 101 个提交最终 Git 哈希是 g897c7ad。这个快照版比很多人在用的官方 2.24 稳定版更新修复了一批跟服务重启、进程树清理相关的旧问题。适合被「服务明明在跑但日志不写」「脚本半夜崩了没人知道」折磨的运维和开发。我第一次接触 NSSM 是因为一个 Java 后端服务在 Windows Server 上动不动就退出任务计划程序又没法自动拉起。后来把所有启动命令塞进 NSSM世界清净了。如果你也遇到过「进程还在但服务已停止」「程序退出后子进程没人管」「日志文件越来越大不敢删」这类问题这篇笔记能帮你把 NSSM 从「能用」用到「好使」尤其会针对 2.24-101-g897c7ad 这个快照版本说清楚它和旧版的差别。2. 先跑通最小实例用 nssm 把 bat 脚本注册成 Windows 服务2.1 拿到 NSSM选 64 位还是 32 位放哪最省心NSSM 是一个单文件 exe下载下来不需要安装复制到某个目录就能用。常见做法是把nssm.exe放到C:\Windows\System32下这样 cmd 和 PowerShell 里直接敲nssm就能识别。如果你的程序是 32 位的但 Windows 系统是 64 位的建议用 64 位版本的 nssm.exe因为它只是管理进程不需要和目标程序位数一致。用where nssm验证一下命令是否可用。对于 nssm-2.24-101-g897c7ad 这个快照版本要注意它属于开发分支。如果你对稳定性要求极高可以先在测试机上跑一周。我一般把它单独放在C:\tools\nssm-2.24-101-g897c7ad目录里和系统里其他版本的 nssm.exe 分开这样升级和回滚都方便不会污染系统路径。2.2 一条命令注册服务install / start / remove 快速上手先从一个最简单的 bat 脚本开始。假设你有C:\myapp\run.bat内容就是启动一个 Python HTTP 服务。用管理员权限打开 CMD执行注册命令nssm install myapp C:\myapp\run.bat nssm start myapp第一行把myapp注册成 Windows 服务程序路径指向run.bat。第二行立即启动。这里有个隐藏细节NSSM 启动 bat 脚本时实际上调用的是cmd.exe /c来执行所以批处理里的相对路径也都能用但工作目录默认不一定是C:\myapp后面会专门说怎么设。如果想删掉服务顺序很重要nssm stop myapp nssm remove myapp confirmconfirm是必须的不加的话 NSSM 会弹窗确认在无人值守脚本里会卡住。删除前先 stop 是为了避免服务还在运行时删注册表导致句柄泄漏。很多新手在这里翻车直接 remove结果进程还活在任务管理器里服务也删不掉。2.3 验证服务真的在跑三条命令别看漏注册完别只看服务列表里写着「正在运行」那不是真的。用下面的命令确认sc query myapp tasklist | findstr python.exesc query看的是服务控制管理器对 NSSM 父进程的状态tasklist看的是实际业务进程。很多时候 NSSM 父进程活着但你的 python.exe 已经退了这就是为什么必须双端验证。另外如果你的 bat 脚本里启动的是 Python建议在 bat 最后加一行pause或让 Python 进程保持前台运行否则脚本一跑完 NSSM 会认为服务结束了。3. 配置项才是灵魂NSSM 的服务参数与启动方式调优3.1 三大配置区域Application、Process、Log 先分清NSSM 的所有配置都保存在注册表HKLM\SYSTEM\CurrentControlSet\Services\服务名\Parameters下但平时不需要直接碰注册表用nssm set命令改就行。配置按作用分成三类Application 是决定「怎么拉起程序」的Process 是决定「程序退出后怎么办」的Log 是决定「标准输出和错误写到哪里、怎么轮转」的。配置区域关键参数作用ApplicationAppDirectory、AppParameters、AppNoConsole设置工作目录、命令行参数、是否显示窗口ProcessAppExit、AppRestartDelay、Throttle控制退出码对应的动作失败后延时重启LogAppStdout、AppStderr、AppRotateFiles、AppRotateBytes重定向标准输出/错误按大小轮转日志初次配置时最容易漏掉AppDirectory。如果你不设NSSM 默认工作目录是C:\Windows\System32程序里凡是写相对路径的地方都会找不到文件。我见过一个 Java 程序启动后立刻报错找不到application.yml排查半天发现是工作目录不对。所以用nssm set设置工作目录是第一步。3.2 用 nssm set 修改自动重启与退出码假设你的程序退出码是 1 表示异常退出0 表示正常结束。你可能希望异常退出时自动重启正常退出时保持暂停。用下面这组命令nssm set myapp AppDirectory C:\myapp nssm set myapp AppExit 1 Restart nssm set myapp AppRestartDelay 5000 nssm set myapp AppStopMethodSkip 0第一行设置工作目录第二行告诉 NSSM退出码为 1 时执行 Restart。第三行重启前等 5 秒避免程序陷入快速死循环。最后一行AppStopMethodSkip设置为 0意思是服务停止时不要跳过任何进程关闭步骤这个参数在后面避坑章节会详细展开。需要特别强调的是AppExit可以不只配一个退出码。你还可以写nssm set myapp AppExit 2 Exit让退出码 2 直接退出不重启。但default这个关键词一定要慎用一旦设置成default Restart所有没单独定义的退出码都会重启包括程序自己正常 return 0 的情况。我的习惯是只对明确知道的异常退出码配 Restart稳一点。3.3 用 GUI 改参数和导出配置如果你不喜欢命令行可以运行nssm edit myapp直接打开图形界面。界面里的「Application」页签对应 Application 配置「Process」页签对应退出动作「I/O」页签对应日志重定向。改完点「Edit service」保存服务会重启一次。图形界面最大的价值是让你直观看到默认值。例如AppStopMethodConsole默认是 2000 毫秒AppStopMethodWindow默认也是 2000 毫秒AppStopMethodThreads默认是 2000 毫秒。这些默认值决定了 NSSM 停止服务时如何关闭你的程序先发控制台事件再发窗口消息最后等待线程结束。如果你的程序对这几个阶段处理不好就会出现「服务停止后进程还活着」的问题。要导出配置做备份可以用reg export导出注册表项reg export HKLM\SYSTEM\CurrentControlSet\Services\myapp myapp-service.reg后面升级 NSSM 版本时这个备份能让你快速对比新版本的参数有没有被重置。我通常每次调整完配置就导出一份文件不大但真的是后悔药。4. 从 2.24 升级到 101-g897c7ad版本迁移与兼容性排查4.1 版本号怎么读2.24、101、g897c7ad 分别代表什么如果你熟悉 Git一眼就能看出来这是git describe的输出格式。2.24是最近一个 tag101表示从那个 tag 之后又经历了 101 次提交g897c7ad表示当前提交的短哈希前缀g是 Git 的标记。翻译成人话这是基于 2.24 稳定版往后又修了很多东西的开发快照。在升级前先了解当前版本的命令nssm version会输出版本信息。旧版 2.24 的版本输出比较简单而这个快照版输出里能直接看到提交哈希。如果你的生产环境还在用 2.24并且你遇到过下面这些现象——服务停止后子进程残留、日志轮转不生效、重启间隔不受控——那这个快照很可能就是为你准备的。4.2 升级替换的完整步骤先备份再换文件升级 NSSM 本身只需要替换一个 exe但替换的时机和顺序很讲究。我踩过坑直接覆盖 exe 然后重启服务发现服务起不来因为新版本对某些参数的校验更严格了。所以我现在按这个流程来nssm stop myapp reg export HKLM\SYSTEM\CurrentControlSet\Services\myapp myapp-backup.reg copy /Y C:\tools\nssm-2.24-101-g897c7ad\win64\nssm.exe C:\Windows\System32\nssm.exe nssm start myapp sc query myapp tasklist | findstr python.exe第一步停止服务是为了防止 nssm.exe 正被占用。第二步导出注册表是万一新版本不兼容可以立刻用reg /s还原。第三步替换 exe 后第四步启动服务最后确认业务进程真的起来了。这里有个细节NSSM 服务的主映像路径指向的是nssm.exe。如果 Windows 系统目录里同时存在旧版而服务注册时写的是绝对路径你需要用sc qc myapp查看BINARY_PATH_NAME确认它指向的是不是你刚替换的那个文件。很多人把 nssm.exe 放到自定义目录然后服务路径还指向旧位置结果升级了个寂寞。4.3 为什么这个快照版值得关注几个社区公认的老毛病按理说 2.24 是稳定版但它有一个比较常见的毛病服务停止时如果目标程序不响应控制台事件NSSM 会一直等直到超时后强制杀掉整个进程树。在 2.24 上这个强制杀掉的行为偶尔会漏掉子进程尤其是你启动的是 bat 脚本脚本里又启动了 PythonPython 再拉起子进程整个树容易断掉。2.24-101-g897c7ad 这个快照里明显的感觉是进程树清理更彻底了服务停止后tasklist里不会再留下一堆孤儿进程。另一个改进是日志轮转的稳定性。2.24 的在线轮转偶尔会在文件被占用时跳过新的快照对AppRotateOnline处理得更果断到点就切文件不再卡句柄。如果你现在正被「日志文本文还有配套的精品资源点击获取