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.
Files changed (3) hide show
  1. package/cli.mjs +12 -4
  2. package/package.json +1 -1
  3. 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 || "(无报错输出,可能是被杀毒软件静默拦截)"}\n\x1b[31m===============================\x1b[0m\n`);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "panrouter",
3
- "version": "3.3.0",
3
+ "version": "3.5.0",
4
4
  "description": "让 Claude Code 免费使用 DeepSeek 等模型,无需 API Key",
5
5
  "type": "module",
6
6
  "bin": {
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" # 遇到错误直接抛出,由 try-catch 捕获写日志
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)) { $nodePath = "node" }
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
- Start-Process -FilePath $nodePath -ArgumentList "`"$serverPath`"" -WorkingDirectory $scriptDir -WindowStyle Hidden
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. 端口探测报错 (忽略并继续): $($_.Exception.Message)" | Out-File $logFile -Append
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", "服务已重启", [System.Windows.Forms.ToolTipIcon]::Info)
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
  }