@flun/windows 3.0.10 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -14
- package/LICENSE +28 -12
- package/README.md +294 -174
- package/bin/cli.js +218 -0
- package/bin/winsw/winsw.exe.config +1 -1
- package/copy-files.js +34 -34
- package/index.d.ts +133 -129
- package/lib/binaries.js +133 -132
- package/lib/cmd.js +4 -4
- package/lib/daemon.js +82 -77
- package/lib/eventlog.js +13 -7
- package/lib/shared.js +5 -3
- package/lib/winsw.js +15 -13
- package/lib/wrapper.js +15 -15
- package/package.json +7 -3
- package/win-service.config.js +68 -0
- package/sevWin.js +0 -18
package/README.md
CHANGED
|
@@ -1,32 +1,64 @@
|
|
|
1
1
|
# @flun/windows
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## 简介
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
本工具库能将您的 Node.js 应用程序作为 Windows 后台服务来运行和管理,支持服务的安装、启动、停止及卸载全流程;
|
|
6
|
+
还提供事件日志等功能,它主要用于面向生产环境应用程序的部署与运维;如需联系,邮箱: [open@flun.top](mailto:open@flun.top)
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
- **兼容方式**:Node.js ≥ 23.5.0 原生支持 `require(esm)`;22.12+ 需开启 `--experimental-require-module` 标志;
|
|
9
|
-
- **重要**:本文档所有示例均采用 **ESM 标准**,请确保你的项目 `package.json` 中已设置 `"type": "module"`,或将脚本后缀改为 `.mjs`;
|
|
8
|
+
**本包基于 ESM 模块系统编写;**
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
- **推荐方式**:使用 `import` / `export` 语法,静态分析更友好,工具链兼容性最佳;
|
|
11
|
+
- **兼容方式**:Node.js ≥ 23.5.0 原生支持 `require(esm)`;22.12+ 需开启 `--experimental-require-module` 标志;
|
|
12
|
+
- **重要**:本文档所有示例均采用 **ESM 标准**,请确保你的项目 `package.json` 中已设置 `"type": "module"`,或将脚本后缀改为
|
|
13
|
+
`.mjs`;
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
## 特性
|
|
16
|
+
|
|
17
|
+
@flun/windows 提供以下功能:
|
|
18
|
+
|
|
19
|
+
- **服务管理**:将 Node.js 脚本作为原生 Windows 服务运行(含监控功能)
|
|
20
|
+
- **事件日志**:写入 Windows 事件日志
|
|
21
|
+
- **系统命令**:
|
|
22
|
+
- _权限提升_:以管理员权限运行命令(会触发 UAC 确认)
|
|
23
|
+
- _Sudo 执行_:以管理员身份执行命令
|
|
24
|
+
- _权限检测_:检测当前用户是否具有管理员权限
|
|
25
|
+
- _进程列表_:列出运行中的 Windows 进程/服务
|
|
26
|
+
- _终止进程_:通过 PID 终止特定进程
|
|
14
27
|
|
|
15
|
-
- **服务管理**:将 Node.js 脚本作为原生 Windows 服务运行(含监控功能)
|
|
16
|
-
- **事件日志**:写入 Windows 事件日志
|
|
17
|
-
- **系统命令**:
|
|
18
|
-
- _权限提升_:以管理员权限运行命令(会触发 UAC 确认)
|
|
19
|
-
- _Sudo 执行_:以管理员身份执行命令
|
|
20
|
-
- _权限检测_:检测当前用户是否具有管理员权限
|
|
21
|
-
- _进程列表_:列出运行中的 Windows 进程/服务
|
|
22
|
-
- _终止进程_:通过 PID 终止特定进程
|
|
23
28
|
---
|
|
24
29
|
|
|
25
|
-
##
|
|
30
|
+
## 包目录结构
|
|
31
|
+
|
|
32
|
+
随包发布的文件:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
@flun/windows/
|
|
36
|
+
├── index.js 库入口,导出 elevate / sudo / isAdminUser / kill / list / Service / EventLogger
|
|
37
|
+
├── index.d.ts 类型声明
|
|
38
|
+
├── lib/binaries.js 外部二进制定位与提权调用
|
|
39
|
+
├── lib/cmd.js 进程列表与终止
|
|
40
|
+
├── lib/daemon.js Windows 服务管理类
|
|
41
|
+
├── lib/eventlog.js 事件日志写入
|
|
42
|
+
├── lib/winsw.js winsw 配置生成
|
|
43
|
+
├── lib/wrapper.js 进程包装器
|
|
44
|
+
├── lib/shared.js 共享工具函数
|
|
45
|
+
├── bin/winsw/ winsw 可执行文件(内部资源,非命令)
|
|
46
|
+
├── bin/elevate.vbs UAC 提权脚本(内部资源,非命令)
|
|
47
|
+
├── bin/cli.js 命令行入口
|
|
48
|
+
├── win-service.config.js 服务配置模板(全量字段,必填项带 *)
|
|
49
|
+
├── copy-files.js postinstall 复制二进制资源
|
|
50
|
+
├── package.json 包配置
|
|
51
|
+
├── README.md 本文件
|
|
52
|
+
├── CHANGELOG.md 更新日志
|
|
53
|
+
└── LICENSE 许可
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 安装前准备
|
|
26
57
|
|
|
27
58
|
### 允许安装脚本执行
|
|
28
59
|
|
|
29
|
-
|
|
60
|
+
本包在安装时可能触发某些依赖包的自动脚本(如 `postinstall` 等);如果你的 npm 全局配置或项目配置禁止了脚本执行(例如设置了
|
|
61
|
+
`ignore-scripts=true`),可能会导致安装不完整或运行时异常;
|
|
30
62
|
|
|
31
63
|
推荐在项目根目录的 `package.json` 中添加 `allowScripts` 字段,显式放行本包及其依赖的脚本:
|
|
32
64
|
|
|
@@ -34,75 +66,167 @@
|
|
|
34
66
|
{
|
|
35
67
|
"allowScripts": {
|
|
36
68
|
"@flun/windows": true
|
|
37
|
-
// 如果依赖的其他包(如 bcrypt、electron-winstaller 等)也有脚本,请按需添加,格式相同
|
|
38
69
|
}
|
|
39
70
|
}
|
|
40
71
|
```
|
|
41
72
|
|
|
42
|
-
> 如果你信任所有安装包,也可以直接在项目 `.npmrc` 中设置 `allow-scripts = false`(表示关闭脚本拦截,所有脚本均允许执行),或删除 `ignore-scripts` 字段;
|
|
43
|
-
|
|
44
73
|
---
|
|
45
74
|
|
|
46
75
|
## 安装
|
|
47
76
|
|
|
48
|
-
|
|
77
|
+
全局安装后可直接使用 `windows` 命令:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npm i -g @flun/windows
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
局部安装时用 `npx windows` 调用,或在 `package.json` 的 `scripts` 中直接写 `windows`:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
npm i @flun/windows
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 无原生模块依赖
|
|
90
|
+
|
|
91
|
+
Windows 上的原生 Node 模块安装复杂,通常需要 Visual Studio 和 node-gyp 进行编译;@flun/windows **不依赖任何原生模块**,
|
|
92
|
+
所有二进制工具均已预打包,无需安装 Visual Studio 等编译环境;
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## 命令行
|
|
49
97
|
|
|
50
|
-
|
|
98
|
+
命令在 `npm scripts` 中运行时,工作目录取 `INIT_CWD`,即发起 npm 命令的项目根目录;
|
|
51
99
|
|
|
52
|
-
|
|
100
|
+
```bash
|
|
101
|
+
windows <命令> [--键 值]
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
服务类命令默认读取你项目根目录的配置文件(`win-service.config.js`) ;如果命令行指令后加了 `--键 值` ,那么以命令配置为准;
|
|
105
|
+
|
|
106
|
+
### 快速开始
|
|
107
|
+
编辑`win-service.config.js`文件,填写带 `*` 的必填项 `name` 与 `script`;
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
windows install # 按配置文件安装并启动服务
|
|
111
|
+
|
|
112
|
+
windows install --name MyApp --script D:\app\main.js # 带参安装并启动
|
|
113
|
+
```
|
|
53
114
|
|
|
54
|
-
|
|
115
|
+
安装后默认启动服务;若只需安装,加 `--no-start`;
|
|
55
116
|
|
|
56
|
-
|
|
117
|
+
全局安装不触发 `postinstall`,可用 `windows example` 手动生成模板;
|
|
57
118
|
|
|
58
|
-
|
|
119
|
+
### 命令
|
|
59
120
|
|
|
60
|
-
|
|
121
|
+
#### 服务类
|
|
61
122
|
|
|
62
|
-
|
|
123
|
+
| 命令 | 说明 |
|
|
124
|
+
| ------------------ | --------------------------------------------- |
|
|
125
|
+
| `install` | 安装服务,装完默认启动;`--no-start` 只装不启动 |
|
|
126
|
+
| `uninstall` | 卸载服务 |
|
|
127
|
+
| `start` | 启动服务 |
|
|
128
|
+
| `stop` | 停止服务 |
|
|
129
|
+
| `restart` | 重启服务 |
|
|
130
|
+
| `status` | 查询状态,输出 0-3 |
|
|
131
|
+
| `xml` | 输出 winsw 配置 XML |
|
|
132
|
+
| `exe [--dir 目录]` | 生成 winsw 可执行文件 |
|
|
133
|
+
|
|
134
|
+
#### 其它
|
|
135
|
+
|
|
136
|
+
| 命令 | 说明 |
|
|
137
|
+
| ---------------------- | ------------------------------------------- |
|
|
138
|
+
| `list [--verbose]` | 列出运行中的进程 |
|
|
139
|
+
| `kill <pid> [--force]` | 结束进程 |
|
|
140
|
+
| `log <级别> <消息>` | 写事件日志 |
|
|
141
|
+
| `is-admin` | 检查当前是否管理员 |
|
|
142
|
+
| `elevate <命令...>` | 以管理员权限执行命令 |
|
|
143
|
+
| `example` | 生成 `win-service.config.js` 模板到当前项目 |
|
|
144
|
+
| `help` | 显示帮助 |
|
|
145
|
+
|
|
146
|
+
`status` 输出状态码:`0` 不存在;`1` 有服务无文件;`2` 有文件无服务;`3` 完整存在;
|
|
147
|
+
|
|
148
|
+
`log` 的级别取 `info`、`warn`、`error`、`success`、`failure`;`success` 与 `failure`
|
|
149
|
+
分别对应 `auditSuccess` 与 `auditFailure`;可加 `--source <名>` 指定事件源,`--id <号>` 指定事件 ID;
|
|
150
|
+
|
|
151
|
+
### 命令行参数示例
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
# 前提:win-service.config.js 已提供 name 与 script;以下每条只覆盖部分字段
|
|
155
|
+
|
|
156
|
+
# 1. 覆盖描述:装出的服务在服务管理器中显示为该描述
|
|
157
|
+
windows install --description "我的服务"
|
|
158
|
+
|
|
159
|
+
# 2. 覆盖 node 启动参数:服务以 --harmony 模式运行
|
|
160
|
+
windows install --nodeOptions '["--harmony"]'
|
|
161
|
+
|
|
162
|
+
# 3. 打开出错退出:脚本运行出错时进程直接退出(省略值即 true)
|
|
163
|
+
windows install --abortOnError
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
字符串值用双引号,JSON 值用单引号(避免 shell 解析方括号);值先按 JSON 解析,失败则按字符串处理;
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## 函数方式
|
|
171
|
+
|
|
172
|
+
### 快速开始
|
|
173
|
+
配置(`win-service.config.js`)必填项,详见[参考配置](#参考配置);
|
|
63
174
|
|
|
64
175
|
```js
|
|
176
|
+
// 创建并安装一个 Windows 服务:
|
|
65
177
|
import { Service } from '@flun/windows';
|
|
178
|
+
import config from './win-service.config.js';
|
|
66
179
|
|
|
67
|
-
|
|
68
|
-
const svc = new Service({
|
|
69
|
-
name: 'Hello World',
|
|
70
|
-
description: 'nodejs.org 示例服务器',
|
|
71
|
-
script: 'C:\\path\\to\\helloworld.js',
|
|
72
|
-
nodeOptions: [
|
|
73
|
-
'--harmony',
|
|
74
|
-
'--max-old-space-size=4096'
|
|
75
|
-
]
|
|
76
|
-
// ===== 其它可选配置 =====
|
|
77
|
-
//, maxRetries: null // 最大重试次数(默认null,表示忽略)
|
|
78
|
-
//, maxRestarts: 3 // 60秒内最大重启次数(默认3)
|
|
79
|
-
//, stoptimeout: 30 // 停止服务超时时间(秒,默认30)
|
|
80
|
-
//, wait: 1 // 重启等待时间(秒,默认1)
|
|
81
|
-
//, scriptOptions: '' // 传递给脚本的参数(默认空字符串)
|
|
82
|
-
//, stopparentfirst: false // 是否先停止父进程(默认false)
|
|
83
|
-
//, abortOnError: false // 遇到错误是否退出进程(默认false)
|
|
84
|
-
//, grow: 0.25 // 重启等待时间增长比例(默认0.25即25%)
|
|
85
|
-
//, logpath: null // 日志文件路径(默认null,使用默认路径)
|
|
86
|
-
//, logmode: 'rotate' // 日志模式('reset', 'roll', 'append')
|
|
87
|
-
//, execPath: process.execPath // Node.js可执行文件路径(默认当前Node)
|
|
88
|
-
//, logOnAs: {} // 服务运行的用户凭据('domain'、'account'、'password'和'mungeCredentialsAfterInstall')
|
|
89
|
-
//, env: undefined // 环境变量(默认:undefined)
|
|
90
|
-
//, logging: null // 日志配置(默认:mode = 'append', pattern = 'yyyMMdd', sizeThreshold = 10240, keepFiles = 8)
|
|
91
|
-
//, allowServiceLogon: undefined // 允许服务登录(默认undefined)
|
|
92
|
-
//, workingDirectory: process.cwd() // 工作目录(默认当前目录)
|
|
93
|
-
});
|
|
180
|
+
const svc = new Service(config);
|
|
94
181
|
|
|
95
|
-
//
|
|
96
|
-
svc.
|
|
97
|
-
|
|
98
|
-
|
|
182
|
+
// 安装并自动启动服务(默认)
|
|
183
|
+
svc.install();
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
安装后可用 Windows 服务管理器、`NET START/STOP` 或 `sc` 命令管理;
|
|
187
|
+
|
|
188
|
+
### 配置功能
|
|
189
|
+
|
|
190
|
+
| 功能 | 类型 | 说明 |
|
|
191
|
+
| ------------- | ---- | ------------------------------------- |
|
|
192
|
+
| `Service` | 类 | Windows 服务管理,安装/卸载/启停 |
|
|
193
|
+
| `EventLogger` | 类 | 写入 Windows 事件日志 |
|
|
194
|
+
| `elevate` | 函数 | 以管理员权限运行命令(触发 UAC) |
|
|
195
|
+
| `sudo` | 函数 | 以管理员身份执行命令(需系统启用 sudo) |
|
|
196
|
+
| `isAdminUser` | 函数 | 检测当前用户是否具有管理员权限 |
|
|
197
|
+
| `list` | 函数 | 列出运行中的进程/服务 |
|
|
198
|
+
| `kill` | 函数 | 通过 PID 终止进程 |
|
|
199
|
+
|
|
200
|
+
以下各节为各导出的详细用法;
|
|
99
201
|
|
|
202
|
+
### Windows 服务管理
|
|
203
|
+
|
|
204
|
+
@flun/windows 可将 Node.js 脚本转换为 Windows 服务;注意:创建服务需要管理员权限!!
|
|
205
|
+
|
|
206
|
+
以下示例仅列常用项,全部可配置字段与默认值见[参考配置](#参考配置);
|
|
207
|
+
|
|
208
|
+
基础示例:
|
|
209
|
+
|
|
210
|
+
```js
|
|
211
|
+
import { Service } from '@flun/windows';
|
|
212
|
+
import config from './win-service.config.js';
|
|
213
|
+
|
|
214
|
+
const svc = new Service(config);
|
|
215
|
+
|
|
216
|
+
// 安装并自动启动服务(默认)
|
|
100
217
|
svc.install();
|
|
218
|
+
|
|
219
|
+
// 只安装,不自动启动
|
|
220
|
+
// svc.install(undefined, false);
|
|
101
221
|
```
|
|
102
222
|
|
|
103
223
|
服务创建后可通过 Windows 服务管理器、`NET START/STOP` 或 `sc` 命令管理;
|
|
104
224
|
|
|
105
|
-
|
|
225
|
+
默认情况下,各方法执行后会在终端打印结果(如 `服务安装完成;`);
|
|
226
|
+
若将本包嵌入到生产项目,终端输出会混入宿主日志,可在配置中设 `quiet: true`,
|
|
227
|
+
此时库只发事件、不打印,通过下方事件获取状态;命令行方式恒为 `quiet`,不受此字段影响;
|
|
228
|
+
|
|
229
|
+
#### 支持的事件
|
|
106
230
|
|
|
107
231
|
- _install_ - 服务安装完成
|
|
108
232
|
- _alreadyinstalled_ - 服务已存在
|
|
@@ -113,117 +237,87 @@ svc.install();
|
|
|
113
237
|
- _stop_ - 服务停止
|
|
114
238
|
- _error_ - 发生错误
|
|
115
239
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
通过 `scriptOptions` 配置:
|
|
119
|
-
|
|
120
|
-
```js
|
|
121
|
-
import { Service } from '@flun/windows';
|
|
122
|
-
const svc1 = new Service({
|
|
123
|
-
..., // 基本配置略...
|
|
124
|
-
scriptOptions: '-c C:\\config\\special.conf -i'
|
|
125
|
-
});
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
### 环境变量设置
|
|
240
|
+
#### 环境变量设置
|
|
129
241
|
|
|
130
|
-
`@flun/windows` 会自动向服务进程注入 `USERPROFILE`
|
|
242
|
+
`@flun/windows` 会自动向服务进程注入 `USERPROFILE` 环境变量,其值为**安装服务时当前登录用户的主目录**(例如
|
|
243
|
+
`C:\Users\你的用户名`;
|
|
131
244
|
这确保了服务中调用 `os.homedir()` 能返回正确的用户目录,即使服务以 `LocalSystem` 等系统账户运;
|
|
132
245
|
|
|
133
|
-
**你通常不需要手动设置 `USERPROFILE
|
|
246
|
+
**你通常不需要手动设置 `USERPROFILE`**,如需添加其他自定义环境变量,可按以下方式:
|
|
134
247
|
|
|
135
248
|
```js
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
script: 'C:\\app\\server.js',
|
|
249
|
+
// win-service.config.js
|
|
250
|
+
export default {
|
|
251
|
+
// ...其余字段
|
|
140
252
|
env: {
|
|
141
253
|
MY_CUSTOM_VAR: 'some value',
|
|
142
|
-
ANOTHER_VAR: 'hello'
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
// 也支持数组形式
|
|
146
|
-
const svc2 = new Service({
|
|
147
|
-
...,
|
|
148
|
-
env: [
|
|
149
|
-
{ name: 'VAR1', value: 'value1' },
|
|
150
|
-
{ name: 'VAR2', value: 'value2' }
|
|
151
|
-
]
|
|
152
|
-
});
|
|
254
|
+
ANOTHER_VAR: 'hello',
|
|
255
|
+
},
|
|
256
|
+
};
|
|
153
257
|
```
|
|
154
258
|
|
|
155
|
-
|
|
259
|
+
也支持数组形式,元素为 `{ name, value }`:
|
|
156
260
|
|
|
157
261
|
```js
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
262
|
+
// win-service.config.js
|
|
263
|
+
export default {
|
|
264
|
+
// ...其余字段
|
|
265
|
+
env: [
|
|
266
|
+
{ name: 'VAR1', value: 'value1' },
|
|
267
|
+
{ name: 'VAR2', value: 'value2' },
|
|
268
|
+
],
|
|
269
|
+
};
|
|
163
270
|
```
|
|
164
271
|
|
|
165
|
-
|
|
272
|
+
#### 用户账户配置
|
|
166
273
|
|
|
167
274
|
```js
|
|
168
275
|
import { Service } from '@flun/windows';
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
276
|
+
import config from './win-service.config.js';
|
|
277
|
+
|
|
278
|
+
const svc = new Service(config);
|
|
172
279
|
|
|
173
280
|
// 安装后指定特定用户或凭据以登录运行
|
|
174
281
|
svc.logOnAs.domain = 'mydomain.local';
|
|
175
282
|
svc.logOnAs.account = 'username';
|
|
176
283
|
svc.logOnAs.password = 'password';
|
|
177
|
-
svc.logOnAs.mungeCredentialsAfterInstall
|
|
284
|
+
svc.logOnAs.mungeCredentialsAfterInstall = true; // 默认
|
|
178
285
|
```
|
|
179
|
-
>
|
|
286
|
+
> **提示**:即使你使用默认的 `LocalSystem` 账户运行服务,`@flun/windows` 也会通过自动注入 `USERPROFILE` 环境变量,
|
|
287
|
+
使你的应用能够正确获取当前登录用户的目录(例如读取用户目录下的配置文件);因此,你不需要为了修正 `os.homedir()` 而特意配置
|
|
288
|
+
`logOnAs` 账户和密码;
|
|
180
289
|
|
|
181
|
-
|
|
290
|
+
#### 服务卸载
|
|
182
291
|
|
|
183
292
|
```js
|
|
184
293
|
import { Service } from '@flun/windows';
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
294
|
+
import config from './win-service.config.js';
|
|
295
|
+
|
|
296
|
+
const svc = new Service(config);
|
|
188
297
|
svc.on('uninstall', ()=>{
|
|
189
298
|
console.log('卸载完成');
|
|
190
|
-
console.log('
|
|
191
|
-
// svc.exists
|
|
299
|
+
console.log('服务是否存在:', svc.exists);
|
|
300
|
+
// svc.exists 返回值说明:
|
|
192
301
|
// 0: 服务和相关文件没有
|
|
193
|
-
// 1:
|
|
194
|
-
// 2:
|
|
195
|
-
// 3:
|
|
302
|
+
// 1: 服务已注册但相关文件不存在(异常情况)
|
|
303
|
+
// 2: 服务未注册但相关文件存在(文件残留)
|
|
304
|
+
// 3: 服务已注册且相关文件存在(正常状态)
|
|
196
305
|
});
|
|
197
306
|
|
|
198
307
|
svc.uninstall();
|
|
199
308
|
```
|
|
200
309
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
### 智能重启机制
|
|
310
|
+
注:卸载仅移除服务相关文件,**不会删除您的 Node.js 脚本**;
|
|
204
311
|
|
|
205
|
-
|
|
312
|
+
#### 服务实现原理
|
|
206
313
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const svc = new Service({
|
|
210
|
-
..., // 基本配置略...
|
|
211
|
-
wait: 2, // 初始等待时间(秒)
|
|
212
|
-
grow: 0.5, // 等待时间增长比例(50%)
|
|
213
|
-
maxRetries: 5, // 最大重试次数
|
|
214
|
-
maxRestarts: 3 // 60秒内最大重启次数
|
|
215
|
-
});
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
### 服务实现原理
|
|
219
|
-
|
|
220
|
-
使用 [winsw]为每个服务生成独立的 `.exe` 和 `.xml` 配置文件,存储在脚本所在目录的 `daemon` 子文件夹中;服务日志可通过 Windows 事件查看器查看;
|
|
314
|
+
使用 [winsw]为每个服务生成独立的 `.exe` 和 `.xml` 配置文件,存储在脚本所在目录的 `daemon` 子文件夹中;服务日志可通过 Windows
|
|
315
|
+
事件查看器查看;
|
|
221
316
|
此外,服务启动时会自动设置 `USERPROFILE` 环境变量为安装服务时当前用户的用户目录,保证路径相关 API 的行为与预期一致;
|
|
222
|
-
---
|
|
223
317
|
|
|
224
|
-
|
|
318
|
+
### 事件日志系统
|
|
225
319
|
|
|
226
|
-
@flun/windows 提供非 C++
|
|
320
|
+
@flun/windows 提供非 C++ 依赖的事件日志功能:
|
|
227
321
|
|
|
228
322
|
```js
|
|
229
323
|
import { EventLogger } from '@flun/windows';
|
|
@@ -246,30 +340,25 @@ const eLog2 = new EventLogger({
|
|
|
246
340
|
});
|
|
247
341
|
```
|
|
248
342
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
# 系统命令工具
|
|
343
|
+
### 系统命令工具
|
|
252
344
|
|
|
253
|
-
|
|
345
|
+
#### elevate(权限提升)
|
|
254
346
|
|
|
255
|
-
`elevate` 类似于 Linux/Mac 上的 `sudo
|
|
347
|
+
`elevate` 类似于 Linux/Mac 上的 `sudo`,它会尝试将当前用户的权限提升为本地管理员;但要求当前用户具有管理员权限,
|
|
348
|
+
若无管理员权限,命令将失败并返回 `access denied` 错误;
|
|
256
349
|
|
|
257
350
|
系统会弹出 UAC 提示,确认用户是否允许继续;
|
|
258
351
|
|
|
259
|
-
|
|
352
|
+
**语法**:`elevate(cmd[, options][, callback])`
|
|
260
353
|
|
|
261
|
-
|
|
354
|
+
**示例**:
|
|
262
355
|
|
|
263
356
|
```js
|
|
264
357
|
import { elevate } from '@flun/windows';
|
|
265
358
|
// 基本用法
|
|
266
359
|
elevate('echo "Hello World" && whoami',{}, (error, stdout, stderr) => {
|
|
267
|
-
if (error)
|
|
268
|
-
|
|
269
|
-
} else {
|
|
270
|
-
console.log('执行成功,输出:', stdout);
|
|
271
|
-
console.log('错误输出:', stderr);
|
|
272
|
-
}
|
|
360
|
+
if (error) console.error('执行失败:', error);
|
|
361
|
+
else console.log('执行成功,输出:', stdout), console.log('错误输出:', stderr);
|
|
273
362
|
});
|
|
274
363
|
|
|
275
364
|
// 带选项参数
|
|
@@ -280,18 +369,19 @@ elevate('echo "Hello World" && whoami', (err, stdout)=> { }); // options视为
|
|
|
280
369
|
elevate('echo "Hello World" && whoami'); // 无回调
|
|
281
370
|
```
|
|
282
371
|
|
|
283
|
-
|
|
372
|
+
#### sudo(管理员执行)
|
|
284
373
|
|
|
285
|
-
`sudo` 与 Linux/Mac 上的 `sudo` 类似;与 `elevate`
|
|
374
|
+
`sudo` 与 Linux/Mac 上的 `sudo` 类似;与 `elevate` 雷同,但稳定性更高,这仍要求用户具有管理员权限,
|
|
375
|
+
并且需在Windows上启用sudo命令,否则命令将失败;
|
|
286
376
|
|
|
287
|
-
|
|
377
|
+
**语法**:`sudo(cmd[, options][, callback])`
|
|
288
378
|
|
|
289
|
-
|
|
290
|
-
- `cmd
|
|
291
|
-
- `options
|
|
292
|
-
- `callback
|
|
379
|
+
**参数说明**:
|
|
380
|
+
- `cmd`:要执行的命令
|
|
381
|
+
- `options`(可选):执行选项
|
|
382
|
+
- `callback`(可选):执行完成后的回调函数
|
|
293
383
|
|
|
294
|
-
|
|
384
|
+
**示例**:
|
|
295
385
|
|
|
296
386
|
```js
|
|
297
387
|
import { sudo } from '@flun/windows';
|
|
@@ -299,10 +389,7 @@ import { sudo } from '@flun/windows';
|
|
|
299
389
|
// 基本用法 - 命令、选项和回调
|
|
300
390
|
sudo('echo "Hello World" && whoami', {}, (error, stdout, stderr) => {
|
|
301
391
|
if (error) console.error('执行失败:', error);
|
|
302
|
-
else
|
|
303
|
-
console.log('执行成功,输出:', stdout);
|
|
304
|
-
console.log('错误输出:', stderr);
|
|
305
|
-
}
|
|
392
|
+
else console.log('执行成功,输出:', stdout), console.log('错误输出:', stderr);
|
|
306
393
|
});
|
|
307
394
|
|
|
308
395
|
// 带选项参数
|
|
@@ -311,13 +398,13 @@ sudo('echo "Hello World" && whoami', {cwd:'C:\\'}, callback);
|
|
|
311
398
|
sudo('echo "Hello World" && whoami' ); // 无回调
|
|
312
399
|
```
|
|
313
400
|
|
|
314
|
-
|
|
401
|
+
#### 管理员权限检测
|
|
315
402
|
|
|
316
403
|
此异步命令用于判断当前用户是否拥有管理员权限;它会向回调函数传递一个布尔值,如果用户是管理员则返回 `true`,否则返回 `false`;
|
|
317
404
|
|
|
318
|
-
|
|
405
|
+
**语法**:`isAdminUser(callback)`
|
|
319
406
|
|
|
320
|
-
|
|
407
|
+
**示例**:
|
|
321
408
|
|
|
322
409
|
```js
|
|
323
410
|
import { isAdminUser } from '@flun/windows';
|
|
@@ -327,7 +414,7 @@ isAdminUser(isAdmin => {
|
|
|
327
414
|
});
|
|
328
415
|
```
|
|
329
416
|
|
|
330
|
-
|
|
417
|
+
#### 进程列表
|
|
331
418
|
|
|
332
419
|
获取运行中的 Windows 进程/服务列表;
|
|
333
420
|
|
|
@@ -338,42 +425,75 @@ list(processes => {
|
|
|
338
425
|
}, true); // true 显示详细信息
|
|
339
426
|
```
|
|
340
427
|
|
|
341
|
-
|
|
428
|
+
#### 终止进程
|
|
342
429
|
|
|
343
|
-
|
|
430
|
+
通过进程 PID 终止特定进程;
|
|
344
431
|
|
|
345
432
|
```js
|
|
346
433
|
import { kill } from '@flun/windows';
|
|
347
|
-
kill(
|
|
434
|
+
kill(PID, () => {
|
|
348
435
|
console.log('进程已终止');
|
|
349
436
|
});
|
|
350
437
|
```
|
|
351
438
|
|
|
352
439
|
---
|
|
353
440
|
|
|
354
|
-
|
|
441
|
+
## 参考配置
|
|
442
|
+
|
|
443
|
+
以下为 `win-service.config.js` 的字段说明,属查阅性内容,使用前无需通读;
|
|
444
|
+
带 * 的字段为必填项;
|
|
445
|
+
|
|
446
|
+
| 参数 | 作用 |
|
|
447
|
+
| ------------------- | -------------------------------------------------------------------------------- |
|
|
448
|
+
| `name` * | 服务名称,同时作为注册表与服务标识;不能含 `<>:"\/` 与 `?*` 及竖线 |
|
|
449
|
+
| `script` * | 启动服务的入口脚本绝对路径 |
|
|
450
|
+
| `description` | 服务描述,显示在服务管理器中;默认空字符串 |
|
|
451
|
+
| `nodeOptions` | 传递给 node 进程的选项;默认 `--harmony` |
|
|
452
|
+
| `scriptOptions` | 传递给脚本的选项;默认空字符串 |
|
|
453
|
+
| `execPath` | node 可执行文件路径;默认取当前进程 `execPath` |
|
|
454
|
+
| `workingDirectory` | 服务工作目录;默认取当前工作目录 |
|
|
455
|
+
| `maxRetries` | 无响应或故障前的最大重试次数;默认 `null`,不启用 |
|
|
456
|
+
| `maxRestarts` | 60 秒内最大重启次数;默认 `3`,`0` 表示不启用 |
|
|
457
|
+
| `stoptimeout` | 停止服务的超时秒数;默认 `30` |
|
|
458
|
+
| `wait` | 脚本停止后等待重启的秒数;默认 `1` |
|
|
459
|
+
| `grow` | 重启等待时间的增长百分比;默认 `0.25` |
|
|
460
|
+
| `abortOnError` | 脚本运行错误时是否退出进程;默认 `false` |
|
|
461
|
+
| `stopparentfirst` | 是否先停止父进程;默认 `false` |
|
|
462
|
+
| `logpath` | 日志文件路径;默认与可执行文件同目录 |
|
|
463
|
+
| `logmode` | 日志模式,取 `rotate`、`truncate`、`append`;默认 `rotate` |
|
|
464
|
+
| `env` | 环境变量,形如 `{ name, value }` 或同构数组 |
|
|
465
|
+
| `logging` | 日志配置对象,可替代 `logmode`;含 `mode`、`pattern`、`sizeThreshold`、`keepFiles` |
|
|
466
|
+
| `logOnAs` | 服务登录凭据,含 `account`、`password`、`domain`、`mungeCredentialsAfterInstall` |
|
|
467
|
+
| `allowServiceLogon` | 是否允许服务登录 |
|
|
468
|
+
| `quiet` | 为 `true` 时不打印执行结果,只发事件;默认 `false`;命令行方式恒为 `true` |
|
|
355
469
|
|
|
356
|
-
|
|
470
|
+
---
|
|
471
|
+
|
|
472
|
+
## 常见问题
|
|
473
|
+
|
|
474
|
+
### elevate 和 sudo 函数常见问题
|
|
357
475
|
|
|
358
|
-
1. **sudo
|
|
476
|
+
1. **sudo 函数执行失败**:这可能是因为 `sudo.exe` 外部工具不兼容当前系统,建议使用 `elevate` 函数作为替代
|
|
359
477
|
|
|
360
|
-
2.
|
|
478
|
+
2. **权限被拒绝**:确保当前用户具有管理员权限,可以运行 `isAdminUser` 函数检查
|
|
361
479
|
|
|
362
|
-
3.
|
|
480
|
+
3. **回调函数未执行**:确保正确传递回调函数,如果不需要回调,可以不传但无法获取执行结果
|
|
363
481
|
|
|
364
482
|
4. **sudo 函数需要在系统中设置并启用sudo**
|
|
365
483
|
|
|
366
|
-
|
|
484
|
+
### 服务管理常见问题
|
|
367
485
|
|
|
368
486
|
- `invalidinstallation` 错误通常表示 daemon 目录文件不完整
|
|
369
487
|
- 卸载时若文件被锁定,可重新运行卸载或手动删除 `daemon` 目录
|
|
370
488
|
|
|
371
489
|
---
|
|
372
490
|
|
|
373
|
-
|
|
491
|
+
## 许可证
|
|
374
492
|
|
|
375
|
-
|
|
493
|
+
winsw 和 sudowin 遵循各自所有者的许可证;@flun/windows 核心代码采用 ISC 许可证(具体内容请见许可证文档)
|
|
494
|
+
|
|
495
|
+
---
|
|
376
496
|
|
|
377
|
-
|
|
497
|
+
## 贡献
|
|
378
498
|
|
|
379
|
-
|
|
499
|
+
感谢所有贡献者,特别感谢 @arthurblake、@hockeytim11 等开发者的贡献;
|