
# NSSM 使用教程（Windows 下的 systemctl 替代方案）
> 适用场景：把 **控制台程序**（如 frpc、openlist、各种 exe/bat/cmd）  
> 做成 **开机自启 + 后台运行 + 崩溃自动重启 + 日志管理** 的 Windows 服务。

---

## 目录
1. **NSSM** 是什么
2. 下载与准备
3. 安装服务（GUI）
4. 安装服务（纯命令行）
5. 服务启停与状态查看
6. 修改服务配置（GUI/命令行）
7. 崩溃自动重启策略
8. 日志捕获与轮转
9. 权限、依赖与进程设置（可选）
10. 卸载服务
11. 常见问题与排错
12. frpc/openlist 成品脚本示例

---

## 1. **NSSM** 是什么
NSSM（Non-Sucking Service Manager）是一个 Windows Service Wrapper，能：
- 把任何控制台程序包装成 Windows 服务
- 进程退出/崩溃时自动重启
- 捕获 stdout/stderr 写日志并支持轮转

---

## 2. 下载与准备
1. 下载 NSSM 压缩包，解压
2. 根据系统位数选择：
   - 64 位：`win64\nssm.exe`
   - 32 位：`win32\nssm.exe`
3. 放到固定目录，例如：
```powershell
C:\tools\nssm\nssm.exe
````
4. （推荐）将 `C:\tools\nssm` 加到系统 PATH

> **注意**：后续所有安装/启动/删除服务命令，都建议在 **管理员 CMD/PowerShell** 中执行。

---

## 3. 安装服务（GUI 最常用）
管理员 CMD：

```bat
nssm install frpc
````

弹出 GUI 后在 **Application** 页填写：
- **Path**：程序路径  
    例：`E:\控制台软件\frpc\frpc.exe`
- **Startup directory**：工作目录  
    例：`E:\控制台软件\frpc`
- **Arguments**：启动参数  
    例：`-c E:\控制台软件\frpc\frpc.ini`

填完点 **Install service**。

---

## 4. 安装服务（纯命令行）

适合脚本化部署：

```bat
nssm install frpc "E:\控制台软件\frpc\frpc.exe" "-c E:\控制台软件\frpc\frpc.ini"
```

然后补充工作目录等：

```bat
nssm set frpc AppDirectory "E:\控制台软件\frpc"
```

---

## 5. 服务启停与状态查看

```bat
nssm start frpc
nssm stop frpc
nssm restart frpc
nssm status frpc
```

常见 `status` 结果：
- `SERVICE_RUNNING`：运行中
- `SERVICE_STOPPED`：已停止

---

## 6. 修改服务配置（GUI / 命令行）

### 6.1 GUI 编辑

```bat
nssm edit frpc
```

### 6.2 命令行修改（set/get/reset/dump）

**通用格式**：

```bat
nssm set   <服务名> <参数名> <值>
nssm get   <服务名> <参数名>
nssm reset <服务名> <参数名>
nssm dump  <服务名>
```

示例：

```bat
nssm set frpc AppDirectory "E:\控制台软件\frpc"
nssm get frpc AppDirectory
nssm dump frpc
```

---

## 7. 崩溃自动重启策略（两层保险）

### 7.1 NSSM 自带 Exit actions

GUI：**Exit actions** 标签页
- **AppExit Default** = `Restart`
- **AppRestartDelay** = `5000`（毫秒）
- **AppThrottle** = `1500`（默认，一般不用改）

命令行等价：

```bat
nssm set frpc AppExit Default Restart
nssm set frpc AppRestartDelay 5000
nssm set frpc AppThrottle 1500
```

### 7.2 Windows 服务“恢复”策略（推荐开启）

`Win + R → services.msc`  
找到服务 → 属性 → **恢复**：
- 第一次失败：重新启动服务
- 第二次失败：重新启动服务
- 后续失败：重新启动服务
- 延迟：5~10 秒

---

## 8. 日志捕获与轮转

### 8.1 捕获 stdout / stderr

GUI：**I/O** 页
- **Output (stdout)**：`C:\logs\frpc.out.log`
- **Error (stderr)**：`C:\logs\frpc.err.log`

命令行：

```bat
nssm set frpc AppStdout "C:\logs\frpc.out.log"
nssm set frpc AppStderr "C:\logs\frpc.err.log"
```

### 8.2 日志轮转

GUI：**File rotation** 页
- 勾 `Rotate while service is running`
- `Rotate files bigger than X bytes`（如 50MB）
- 可选勾 `Replace existing files`

命令行示例（轮转阈值 50MB）：

```bat
nssm set frpc AppRotateFiles 1
nssm set frpc AppRotateOnline 1
nssm set frpc AppRotateBytes 52428800
nssm set frpc AppRotateSeconds 0
```

---

## 9. 权限、依赖与进程设置（可选）

### 9.1 用指定账户跑服务

GUI：**Log on** 页  
默认 `LocalSystem` 已够用。  
需要访问网络共享时才换普通用户。
命令行：

```bat
nssm set frpc ObjectName ".\someuser" "password"
```

### 9.2 设置依赖（等某服务起来再启动）

GUI：**Dependencies** 页  
命令行：

```bat
nssm set frpc DependOnService Tcpip
```

### 9.3 设置优先级/CPU 亲和性

GUI：**Process** 页  
命令行：

```bat
nssm set frpc AppPriority NORMAL_PRIORITY_CLASS
nssm set frpc AppAffinity All
```

---

## 10. 卸载服务（安全删除）

先停再删：

```bat
nssm stop frpc
nssm remove frpc confirm
```

---

## 11. 常见问题与排错

### 11.1 `Can't open service! OpenService(): 拒绝访问`

原因：**没有管理员权限控制服务**

解决：
1. 关闭当前 CMD
2. 以管理员身份打开 CMD 
3. 再执行：

```bat
nssm start frpc
```

### 11.2 服务启动后立刻停止

常见原因：**Path / Arguments / Startup directory 错**
排查：

```bat
nssm edit frpc
nssm dump frpc
```

### 11.3 日志没内容

原因：
- 没设置 `AppStdout/AppStderr`
- 目录没权限

---

## 12. frpc / openlist 成品脚本示例

### 12.1 frpc

```bat
nssm install frpc "E:\控制台软件\frpc\frpc.exe" "-c \"E:\控制台软件\frpc\frpc.ini\""
nssm set frpc AppDirectory "E:\控制台软件\frpc"
nssm set frpc AppStdout "C:\logs\frpc.out.log"
nssm set frpc AppStderr "C:\logs\frpc.err.log"
nssm set frpc AppExit Default Restart
nssm set frpc AppRestartDelay 5000
nssm start frpc
```

### 12.2 openlist（按你实际参数改）

```bat
nssm install openlist "E:\控制台软件\openlist\openlist.exe" "server --config E:\控制台软件\openlist\config.yaml"
nssm set openlist AppDirectory "E:\控制台软件\openlist"
nssm set openlist AppStdout "C:\logs\openlist.out.log"
nssm set openlist AppStderr "C:\logs\openlist.err.log"
nssm set openlist AppExit Default Restart
nssm set openlist AppRestartDelay 5000
nssm start openlist
```

---

## 速查表

```bat
nssm install <name> "<exe>" "<args>"
nssm edit <name>
nssm start|stop|restart <name>
nssm status <name>
nssm set/get/reset <name> <key> [value]
nssm dump <name>
nssm remove <name> confirm
```

---
