panrouter 3.4.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 +8 -11
- package/package.json +1 -1
- package/tray-daemon.ps1 +25 -18
package/cli.mjs
CHANGED
|
@@ -91,17 +91,15 @@ async function startTray() {
|
|
|
91
91
|
const psPath = path.join(__dirname, "tray-daemon.ps1");
|
|
92
92
|
log("..", "正在后台启动代理...", "yellow");
|
|
93
93
|
|
|
94
|
-
//
|
|
95
|
-
// 方案:将脚本内容强制加上 UTF-8 BOM 头 (EF BB BF),存入临时文件后再让 PowerShell 执行。
|
|
96
|
-
let runPsPath = psPath;
|
|
94
|
+
// 【核心修复】:直接在原文件上追加 UTF-8 BOM 头,彻底修复乱码并保持原目录路径不变
|
|
97
95
|
try {
|
|
98
|
-
const tempDir = process.env.TEMP || process.env.TMP || __dirname;
|
|
99
|
-
runPsPath = path.join(tempDir, "panrouter_tray_run.ps1");
|
|
100
96
|
const psContent = fs.readFileSync(psPath, "utf8");
|
|
101
|
-
|
|
102
|
-
|
|
97
|
+
if (!psContent.startsWith("")) {
|
|
98
|
+
const bom = Buffer.from([0xEF, 0xBB, 0xBF]);
|
|
99
|
+
fs.writeFileSync(psPath, Buffer.concat([bom, Buffer.from(psContent, "utf8")]));
|
|
100
|
+
}
|
|
103
101
|
} catch (e) {
|
|
104
|
-
|
|
102
|
+
// 忽略权限问题
|
|
105
103
|
}
|
|
106
104
|
|
|
107
105
|
try {
|
|
@@ -140,7 +138,7 @@ async function startTray() {
|
|
|
140
138
|
"-STA",
|
|
141
139
|
"-ExecutionPolicy", "Bypass",
|
|
142
140
|
"-WindowStyle", "Hidden",
|
|
143
|
-
"-File", `"${
|
|
141
|
+
"-File", `"${psPath}"`
|
|
144
142
|
], {
|
|
145
143
|
cwd: __dirname,
|
|
146
144
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
@@ -157,8 +155,7 @@ async function startTray() {
|
|
|
157
155
|
|
|
158
156
|
if (tray.exitCode !== null) {
|
|
159
157
|
log("!!", "托盘进程未能驻留,发生闪退!", "red");
|
|
160
|
-
console.log(`\n\x1b[31m=== PowerShell 启动失败原因 ===\x1b[0m\n${psOutput || "(
|
|
161
|
-
console.log("提示:如果代理可用,你可以暂时无视此错误。");
|
|
158
|
+
console.log(`\n\x1b[31m=== PowerShell 启动失败原因 ===\x1b[0m\n${psOutput || "(无输出)"}\n\x1b[31m===============================\x1b[0m\n`);
|
|
162
159
|
} else {
|
|
163
160
|
tray.unref();
|
|
164
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
|
}
|