panrouter 1.6.1 → 1.7.1
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/cli.mjs +9 -14
- package/daemon.mjs +51 -33
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -140,17 +140,6 @@ async function startServer() {
|
|
|
140
140
|
|
|
141
141
|
// ─── 4. 以托盘模式启动 ──────────────────────────────────────────────────
|
|
142
142
|
|
|
143
|
-
/**
|
|
144
|
-
* 启动 daemon (Node 常驻进程, 管理 server + PS tray)
|
|
145
|
-
*
|
|
146
|
-
* cli.mjs ─→ node daemon.mjs (detached, hidden)
|
|
147
|
-
* ├─ 启动 server.mjs (子进程, detached, hidden)
|
|
148
|
-
* └─ 启动 powershell tray-daemon.ps1 (子进程, hidden)
|
|
149
|
-
* └─ 保持存活, 30s 健康检查
|
|
150
|
-
*
|
|
151
|
-
* key: 用 process.execPath (绝对路径) 启动
|
|
152
|
-
* 避免 VBS/WScript/CMD 的 PATH 查找问题
|
|
153
|
-
*/
|
|
154
143
|
function startTray() {
|
|
155
144
|
const daemonPath = path.join(__dirname, "daemon.mjs");
|
|
156
145
|
|
|
@@ -170,9 +159,15 @@ function startTray() {
|
|
|
170
159
|
});
|
|
171
160
|
child.unref();
|
|
172
161
|
|
|
173
|
-
log("OK", "Pan Router
|
|
174
|
-
console.log("
|
|
175
|
-
|
|
162
|
+
log("OK", "Pan Router 托盘服务已启动", "green");
|
|
163
|
+
console.log("");
|
|
164
|
+
console.log(" \x1b[33m实时查看日志:\x1b[0m");
|
|
165
|
+
console.log(" powershell -Command \"Get-Content -Wait -Tail 20 $env:TEMP\\panrouter-daemon.log\"");
|
|
166
|
+
console.log("");
|
|
167
|
+
console.log(" \x1b[33m查看全部日志:\x1b[0m");
|
|
168
|
+
console.log(" notepad %TEMP%\\panrouter-daemon.log");
|
|
169
|
+
console.log("");
|
|
170
|
+
console.log(" 若 10 秒后图标未出现,请查看日志并反馈");
|
|
176
171
|
|
|
177
172
|
// ─── 主流程 ──────────────────────────────────────────────────────────────
|
|
178
173
|
|
package/daemon.mjs
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Pan Router Daemon (
|
|
4
|
+
* Pan Router Daemon (v5)
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* 3. 保持存活,守护两者
|
|
10
|
-
*
|
|
11
|
-
* 由 cli.mjs --tray 启动 (detached, 无窗口)。
|
|
6
|
+
* 1. spawn server.mjs (detached, hidden) — 正常
|
|
7
|
+
* 2. 用 VBS 启动 PS tray(解决 detached 进程无法创建通知图标的问题)
|
|
8
|
+
* 3. 保持存活,30s 健康检查
|
|
12
9
|
*/
|
|
13
10
|
|
|
14
11
|
import { spawn, execSync } from "node:child_process";
|
|
@@ -20,16 +17,15 @@ import http from "node:http";
|
|
|
20
17
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
21
18
|
const serverPath = path.join(__dirname, "server.mjs");
|
|
22
19
|
const trayPsPath = path.join(__dirname, "tray-daemon.ps1");
|
|
23
|
-
const nodeExe = process.execPath;
|
|
20
|
+
const nodeExe = process.execPath;
|
|
24
21
|
const logPath = path.join(process.env.TEMP || "/tmp", "panrouter-daemon.log");
|
|
25
22
|
|
|
26
23
|
function log(msg) {
|
|
27
24
|
try { fs.appendFileSync(logPath, `${new Date().toISOString().slice(11,19)} ${msg}\n`); } catch {}
|
|
28
25
|
}
|
|
29
26
|
|
|
30
|
-
log("=== Daemon
|
|
27
|
+
log("=== Daemon v5 ===");
|
|
31
28
|
log(`nodeExe=${nodeExe}`);
|
|
32
|
-
log(`serverPath=${serverPath}`);
|
|
33
29
|
|
|
34
30
|
// ─── 1. 杀旧 server ──────────────────────────────
|
|
35
31
|
try {
|
|
@@ -40,19 +36,14 @@ try {
|
|
|
40
36
|
for (const line of out.split("\n")) {
|
|
41
37
|
if (line.includes("server.mjs")) {
|
|
42
38
|
const m = line.match(/(\d+),.*?server\.mjs/);
|
|
43
|
-
if (m) { try { process.kill(parseInt(m[1]), "SIGKILL"); log(`Killed old
|
|
39
|
+
if (m) { try { process.kill(parseInt(m[1]), "SIGKILL"); log(`Killed old PID=${m[1]}`); } catch {} }
|
|
44
40
|
}
|
|
45
41
|
}
|
|
46
42
|
} catch {}
|
|
47
43
|
|
|
48
44
|
// ─── 2. 启动 server.mjs ──────────────────────────
|
|
49
|
-
// 关键: 用 process.execPath (绝对路径), 不用 "node" (可能找不到 PATH)
|
|
50
45
|
const server = spawn(nodeExe, [serverPath], {
|
|
51
|
-
cwd: __dirname,
|
|
52
|
-
stdio: "ignore",
|
|
53
|
-
windowsHide: true,
|
|
54
|
-
detached: true,
|
|
55
|
-
shell: false,
|
|
46
|
+
cwd: __dirname, stdio: "ignore", windowsHide: true, detached: true, shell: false,
|
|
56
47
|
});
|
|
57
48
|
server.unref();
|
|
58
49
|
log(`Server spawned PID=${server.pid || "??"}`);
|
|
@@ -77,29 +68,56 @@ function isOnline() {
|
|
|
77
68
|
}
|
|
78
69
|
log(`Server online=${ready}`);
|
|
79
70
|
|
|
80
|
-
// ─── 4. 启动 PS 托盘
|
|
71
|
+
// ─── 4. 用 VBS 启动 PS 托盘 ─────────────────────
|
|
72
|
+
log("Starting PS tray via VBS...");
|
|
73
|
+
|
|
81
74
|
if (fs.existsSync(trayPsPath)) {
|
|
82
|
-
log(
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
75
|
+
log(`trayPsPath exists: ${trayPsPath}`);
|
|
76
|
+
|
|
77
|
+
// 创建临时的 VBS 启动器
|
|
78
|
+
const vbsContent = `Set WshShell = CreateObject("WScript.Shell")
|
|
79
|
+
Set FSO = CreateObject("Scripting.FileSystemObject")
|
|
80
|
+
' 写诊断日志
|
|
81
|
+
On Error Resume Next
|
|
82
|
+
Dim f : Set f = FSO.OpenTextFile("${(process.env.TEMP || "/tmp").replace(/\\/g, "\\\\")}\\panrouter-vbs.log", 2, True)
|
|
83
|
+
f.WriteLine Now & " VBS started"
|
|
84
|
+
f.Close
|
|
85
|
+
' 启动 PS 托盘
|
|
86
|
+
WshShell.Run "powershell -ExecutionPolicy Bypass -WindowStyle Hidden -STA -File """ & "${trayPsPath.replace(/\\/g, "\\\\")}" & """", 0, False
|
|
87
|
+
If Err.Number <> 0 Then
|
|
88
|
+
Set f = FSO.OpenTextFile("${(process.env.TEMP || "/tmp").replace(/\\/g, "\\\\")}\\panrouter-vbs.log", 8, True)
|
|
89
|
+
f.WriteLine Now & " ERROR: " & Err.Description
|
|
90
|
+
f.Close
|
|
91
|
+
End If
|
|
92
|
+
`;
|
|
93
|
+
const vbsPath = path.join(process.env.TEMP || "/tmp", "panrouter-tray-launcher.vbs");
|
|
94
|
+
try {
|
|
95
|
+
fs.writeFileSync(vbsPath, vbsContent, "utf8");
|
|
96
|
+
log(`VBS written: ${vbsPath}`);
|
|
97
|
+
} catch (e) {
|
|
98
|
+
log(`VBS write FAILED: ${e.message}`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
log(`VBS content:\n${vbsContent}`);
|
|
102
|
+
|
|
103
|
+
// 先试 wscript //B
|
|
104
|
+
try {
|
|
105
|
+
const vbs = spawn("wscript.exe", ["//B", "//NoLogo", vbsPath], {
|
|
106
|
+
stdio: "ignore", windowsHide: true, shell: false,
|
|
107
|
+
});
|
|
108
|
+
vbs.unref();
|
|
109
|
+
log(`VBS spawned via wscript`);
|
|
110
|
+
} catch (e) {
|
|
111
|
+
log(`VBS via wscript FAILED: ${e.message}`);
|
|
112
|
+
}
|
|
94
113
|
} else {
|
|
95
|
-
log(`WARN: tray-daemon.ps1
|
|
114
|
+
log(`WARN: tray-daemon.ps1 NOT FOUND at ${trayPsPath}`);
|
|
96
115
|
}
|
|
97
116
|
|
|
98
117
|
// ─── 5. 保持存活 ────────────────────────────────
|
|
99
|
-
log("Daemon running
|
|
118
|
+
log("Daemon running");
|
|
100
119
|
process.stdin.resume();
|
|
101
120
|
|
|
102
|
-
// 定时检查 server, 挂了就重启
|
|
103
121
|
setInterval(() => {
|
|
104
122
|
isOnline().then(ok => {
|
|
105
123
|
if (!ok) {
|