panrouter 3.3.0 → 3.5.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/cli.mjs +12 -4
- package/package.json +1 -1
- package/tray-daemon.ps1 +25 -18
package/cli.mjs
CHANGED
|
@@ -91,6 +91,17 @@ async function startTray() {
|
|
|
91
91
|
const psPath = path.join(__dirname, "tray-daemon.ps1");
|
|
92
92
|
log("..", "正在后台启动代理...", "yellow");
|
|
93
93
|
|
|
94
|
+
// 【核心修复】:直接在原文件上追加 UTF-8 BOM 头,彻底修复乱码并保持原目录路径不变
|
|
95
|
+
try {
|
|
96
|
+
const psContent = fs.readFileSync(psPath, "utf8");
|
|
97
|
+
if (!psContent.startsWith("")) {
|
|
98
|
+
const bom = Buffer.from([0xEF, 0xBB, 0xBF]);
|
|
99
|
+
fs.writeFileSync(psPath, Buffer.concat([bom, Buffer.from(psContent, "utf8")]));
|
|
100
|
+
}
|
|
101
|
+
} catch (e) {
|
|
102
|
+
// 忽略权限问题
|
|
103
|
+
}
|
|
104
|
+
|
|
94
105
|
try {
|
|
95
106
|
if (process.platform === "win32") {
|
|
96
107
|
execSync('taskkill /f /fi "WINDOWTITLE eq Pan Router*" >nul 2>&1', { stdio: "pipe" });
|
|
@@ -122,7 +133,6 @@ async function startTray() {
|
|
|
122
133
|
|
|
123
134
|
log("..", "正在加载系统托盘...", "yellow");
|
|
124
135
|
|
|
125
|
-
// 【核心修复】:增加 -STA 参数防止 UI 线程崩溃,增加 shell:true 确保一定能找到 powershell
|
|
126
136
|
const tray = spawn("powershell.exe", [
|
|
127
137
|
"-NoProfile",
|
|
128
138
|
"-STA",
|
|
@@ -141,13 +151,11 @@ async function startTray() {
|
|
|
141
151
|
tray.stdout.on("data", d => psOutput += d.toString());
|
|
142
152
|
tray.stderr.on("data", d => psOutput += d.toString());
|
|
143
153
|
|
|
144
|
-
// 监控 2.5 秒,如果闪退,直接打印错误
|
|
145
154
|
await new Promise(rs => setTimeout(rs, 2500));
|
|
146
155
|
|
|
147
156
|
if (tray.exitCode !== null) {
|
|
148
157
|
log("!!", "托盘进程未能驻留,发生闪退!", "red");
|
|
149
|
-
console.log(`\n\x1b[31m=== PowerShell 启动失败原因 ===\x1b[0m\n${psOutput || "(
|
|
150
|
-
console.log("提示:如果代理可用,你可以暂时无视此错误。");
|
|
158
|
+
console.log(`\n\x1b[31m=== PowerShell 启动失败原因 ===\x1b[0m\n${psOutput || "(无输出)"}\n\x1b[31m===============================\x1b[0m\n`);
|
|
151
159
|
} else {
|
|
152
160
|
tray.unref();
|
|
153
161
|
console.log(" 托盘图标应该已在右下角显示。");
|
package/package.json
CHANGED
package/tray-daemon.ps1
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<#
|
|
2
2
|
.SYNOPSIS
|
|
3
|
-
Pan Router 托盘守护脚本 (
|
|
3
|
+
Pan Router 托盘守护脚本 (终极完美版)
|
|
4
4
|
#>
|
|
5
|
-
$ErrorActionPreference = "Stop"
|
|
5
|
+
$ErrorActionPreference = "Stop"
|
|
6
6
|
|
|
7
7
|
$logFile = "$env:TEMP\panrouter_tray.log"
|
|
8
8
|
"--- $(Get-Date -Format 'HH:mm:ss') 托盘脚本启动 ---" | Out-File $logFile
|
|
@@ -16,10 +16,13 @@ try {
|
|
|
16
16
|
$scriptDir = Split-Path $MyInvocation.MyCommand.Path -Parent
|
|
17
17
|
$serverPath = Join-Path $scriptDir "server.mjs"
|
|
18
18
|
|
|
19
|
-
# 拿到 Node 路径
|
|
20
19
|
$nodePath = $env:PANROUTER_NODE
|
|
21
|
-
if ([string]::IsNullOrWhiteSpace($nodePath)) {
|
|
20
|
+
if ([string]::IsNullOrWhiteSpace($nodePath)) {
|
|
21
|
+
$nodeCmd = Get-Command node -ErrorAction SilentlyContinue
|
|
22
|
+
if ($nodeCmd) { $nodePath = $nodeCmd.Source } else { $nodePath = "node" }
|
|
23
|
+
}
|
|
22
24
|
"2. Node 路径: $nodePath" | Out-File $logFile -Append
|
|
25
|
+
" Server 路径: $serverPath" | Out-File $logFile -Append
|
|
23
26
|
|
|
24
27
|
# ─── 管理后台代理 ──────────────────────────────────────────
|
|
25
28
|
function Start-Backend {
|
|
@@ -28,7 +31,22 @@ try {
|
|
|
28
31
|
Where-Object CommandLine -match "server\.mjs" |
|
|
29
32
|
ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
|
|
30
33
|
|
|
31
|
-
|
|
34
|
+
try {
|
|
35
|
+
$psi = New-Object System.Diagnostics.ProcessStartInfo
|
|
36
|
+
$psi.FileName = $nodePath
|
|
37
|
+
$psi.Arguments = "`"$serverPath`""
|
|
38
|
+
$psi.WorkingDirectory = $scriptDir
|
|
39
|
+
$psi.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Hidden
|
|
40
|
+
$psi.CreateNoWindow = $true
|
|
41
|
+
$psi.UseShellExecute = $false
|
|
42
|
+
$psi.RedirectStandardOutput = $true
|
|
43
|
+
$psi.RedirectStandardError = $true
|
|
44
|
+
|
|
45
|
+
$proc = [System.Diagnostics.Process]::Start($psi)
|
|
46
|
+
"-> Node 服务进程已原生启动 (PID: $($proc.Id))" | Out-File $logFile -Append
|
|
47
|
+
} catch {
|
|
48
|
+
"-> Node 进程启动失败: $($_.Exception.Message)" | Out-File $logFile -Append
|
|
49
|
+
}
|
|
32
50
|
}
|
|
33
51
|
|
|
34
52
|
# 检查端口
|
|
@@ -40,7 +58,7 @@ try {
|
|
|
40
58
|
$tcp.Close()
|
|
41
59
|
"3. 端口探测完成,已开放状态: $portOpen" | Out-File $logFile -Append
|
|
42
60
|
} catch {
|
|
43
|
-
"3.
|
|
61
|
+
"3. 端口探测报错: $($_.Exception.Message)" | Out-File $logFile -Append
|
|
44
62
|
}
|
|
45
63
|
|
|
46
64
|
if (-not $portOpen) {
|
|
@@ -51,7 +69,6 @@ try {
|
|
|
51
69
|
$notifyIcon = New-Object System.Windows.Forms.NotifyIcon
|
|
52
70
|
$notifyIcon.Text = "Pan Router (:50816)"
|
|
53
71
|
|
|
54
|
-
# 图标兜底处理
|
|
55
72
|
try {
|
|
56
73
|
$bmp = New-Object System.Drawing.Bitmap(16, 16)
|
|
57
74
|
$g = [System.Drawing.Graphics]::FromImage($bmp)
|
|
@@ -59,26 +76,22 @@ try {
|
|
|
59
76
|
$font = New-Object System.Drawing.Font("Arial", 8, [System.Drawing.FontStyle]::Bold)
|
|
60
77
|
$g.DrawString("P", $font, [System.Drawing.Brushes]::White, 2, 1)
|
|
61
78
|
$notifyIcon.Icon = [System.Drawing.Icon]::FromHandle($bmp.GetHicon())
|
|
62
|
-
"4. 自定义图标绘制成功" | Out-File $logFile -Append
|
|
63
79
|
} catch {
|
|
64
|
-
"4. 画图异常,改用原生盾牌图标: $($_.Exception.Message)" | Out-File $logFile -Append
|
|
65
80
|
$notifyIcon.Icon = [System.Drawing.SystemIcons]::Shield
|
|
66
81
|
}
|
|
67
82
|
|
|
68
83
|
# ─── 原生菜单配置 (ContextMenu) ────────────────────────────
|
|
69
|
-
# 【核心修复】:使用原生的 ContextMenu 代替极易失去焦点的 ContextMenuStrip
|
|
70
84
|
$menu = New-Object System.Windows.Forms.ContextMenu
|
|
71
85
|
|
|
72
86
|
$titleItem = New-Object System.Windows.Forms.MenuItem("Pan Router | :50816")
|
|
73
87
|
$titleItem.Enabled = $false
|
|
74
88
|
$menu.MenuItems.Add($titleItem) | Out-Null
|
|
75
|
-
|
|
76
89
|
$menu.MenuItems.Add("-") | Out-Null
|
|
77
90
|
|
|
78
91
|
$restartItem = New-Object System.Windows.Forms.MenuItem("重启服务")
|
|
79
92
|
$restartItem.Add_Click({
|
|
80
93
|
Start-Backend
|
|
81
|
-
$notifyIcon.ShowBalloonTip(2000, "Pan Router", "
|
|
94
|
+
$notifyIcon.ShowBalloonTip(2000, "Pan Router", "后台代理服务已重新启动 ✓", [System.Windows.Forms.ToolTipIcon]::Info)
|
|
82
95
|
})
|
|
83
96
|
$menu.MenuItems.Add($restartItem) | Out-Null
|
|
84
97
|
|
|
@@ -95,13 +108,11 @@ try {
|
|
|
95
108
|
}
|
|
96
109
|
})
|
|
97
110
|
$menu.MenuItems.Add($autoItem) | Out-Null
|
|
98
|
-
|
|
99
111
|
$menu.MenuItems.Add("-") | Out-Null
|
|
100
112
|
|
|
101
113
|
$exitItem = New-Object System.Windows.Forms.MenuItem("退出")
|
|
102
114
|
$exitItem.Add_Click({
|
|
103
115
|
$notifyIcon.Visible = $false
|
|
104
|
-
"-> 执行退出清理" | Out-File $logFile -Append
|
|
105
116
|
Get-WmiObject Win32_Process -Filter "Name = 'node.exe'" | Where-Object CommandLine -match "server\.mjs" | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
|
|
106
117
|
[System.Windows.Forms.Application]::Exit()
|
|
107
118
|
})
|
|
@@ -112,7 +123,6 @@ try {
|
|
|
112
123
|
"5. 托盘图标已绑定并设置为可见" | Out-File $logFile -Append
|
|
113
124
|
|
|
114
125
|
# ─── 隐形实体主窗口 ─────────────────────────────────────────
|
|
115
|
-
# 【核心修复】:挂载真实的 Form 窗口,防止 Windows 将该 PowerShell UI 线程当做垃圾回收掉
|
|
116
126
|
$form = New-Object System.Windows.Forms.Form
|
|
117
127
|
$form.ShowInTaskbar = $false
|
|
118
128
|
$form.WindowState = [System.Windows.Forms.FormWindowState]::Minimized
|
|
@@ -123,10 +133,7 @@ try {
|
|
|
123
133
|
})
|
|
124
134
|
|
|
125
135
|
[System.Windows.Forms.Application]::Run($form)
|
|
126
|
-
|
|
127
|
-
"7. 程序正常退出" | Out-File $logFile -Append
|
|
128
136
|
} catch {
|
|
129
137
|
"【致命报错】无法完成执行:" | Out-File $logFile -Append
|
|
130
138
|
$_.Exception.Message | Out-File $logFile -Append
|
|
131
|
-
$_.Exception.StackTrace | Out-File $logFile -Append
|
|
132
139
|
}
|