dsh-windows-tray 1.0.7 → 1.0.9

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.
@@ -12,7 +12,7 @@ $URL = "http://127.0.0.1:$PORT"
12
12
  $LOG_DIR = Join-Path (Join-Path $env:USERPROFILE '.dsh\logs') 'dsh-windows-tray' # 本插件专属日志目录 (logs\<插件名>\, 边界规则见 release-standards §3.1)
13
13
  $WT = "$env:LOCALAPPDATA\Microsoft\WindowsApps\wt.exe"
14
14
  $PWSH = 'D:\Program Files (x86)\PowerShell-7.6.4\pwsh.exe'
15
- $TRAY_VERSION = '1.0.7' # 托盘版本 (与 npm 包版本同步, 用于日志/排查)
15
+ $TRAY_VERSION = '1.0.9' # 托盘版本 (与 npm 包版本同步, 用于日志/排查)
16
16
  $TRAY_PKG = 'dsh-windows-tray' # npm 包名 (托盘自更新)
17
17
  $TRAY_SCRIPT = Join-Path $PSScriptRoot 'dsh-tray.ps1'
18
18
 
@@ -85,7 +85,7 @@ function Start-Dsh {
85
85
  if ($pids.Count -gt 0) {
86
86
  Write-Host "[dsh] 已在运行: $URL (PID $($pids -join ','))" -ForegroundColor Green
87
87
  if ($trayStarted) { Write-Host '[tray] 系统托盘已自动启动(右键可控制 DSH)' -ForegroundColor DarkGray }
88
- if ($OpenBrowser) { Start-Process $URL }
88
+ if ($OpenBrowser) { Open-DshWeb }
89
89
  return
90
90
  }
91
91
  Write-Host "[dsh] 启动中 (端口 $PORT)..."
@@ -102,7 +102,7 @@ function Start-Dsh {
102
102
  Write-Host "[dsh] 启动成功: $URL" -ForegroundColor Green
103
103
  if ($trayStarted) { Write-Host '[tray] 系统托盘已自动启动(右键可控制 DSH)' -ForegroundColor DarkGray }
104
104
  Start-Sleep -Seconds 2
105
- if ($OpenBrowser) { Start-Process $URL }
105
+ if ($OpenBrowser) { Open-DshWeb }
106
106
  } else {
107
107
  Write-Host "[dsh] 启动失败: 12 秒内端口 $PORT 未监听" -ForegroundColor Red
108
108
  Write-Host "[dsh] 错误日志: $err(末尾 10 行)"
@@ -207,6 +207,53 @@ function Stop-Tui {
207
207
  }
208
208
  }
209
209
 
210
+ # ---- 打开 Web UI: 智能复用已有标签页 (UIA), 任何失败降级为新开 (最坏=旧行为) ----
211
+ $WEB_TITLE_PREFIX = 'DeepSeek Harness' # dsh web 页面 <title> 前缀 (标题可能带 Edge 的 睡眠/内存 后缀)
212
+ $BROWSER_PROGID_MAP = @{ 'MSEdgeHTM' = 'msedge'; 'ChromeHTML' = 'chrome' } # Chromium ProgId → 进程名; 查不到=降级新开
213
+
214
+ function Open-DshWeb {
215
+ param([string]$Url = $URL)
216
+ try {
217
+ $progId = (Get-ItemProperty 'HKCU:\SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice' -ErrorAction Stop).ProgId
218
+ $procName = $BROWSER_PROGID_MAP[$progId]
219
+ if (-not $procName) { throw "非 Chromium 默认浏览器: $progId" }
220
+ Add-Type -AssemblyName UIAutomationClient -ErrorAction SilentlyContinue
221
+ Add-Type -AssemblyName UIAutomationTypes -ErrorAction SilentlyContinue
222
+ if (-not ('DSH.Win32FG' -as [type])) {
223
+ Add-Type -TypeDefinition @'
224
+ namespace DSH {
225
+ using System;
226
+ using System.Runtime.InteropServices;
227
+ public static class Win32FG {
228
+ [DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr hWnd);
229
+ [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
230
+ }
231
+ }
232
+ '@
233
+ }
234
+ $root = [System.Windows.Automation.AutomationElement]::RootElement
235
+ $winCond = New-Object System.Windows.Automation.PropertyCondition([System.Windows.Automation.AutomationElement]::ClassNameProperty, 'Chrome_WidgetWin_1')
236
+ foreach ($win in $root.FindAll('Children', $winCond)) {
237
+ if ((Get-Process -Id $win.Current.ProcessId -ErrorAction SilentlyContinue).ProcessName -ne $procName) { continue }
238
+ $tabCond = New-Object System.Windows.Automation.PropertyCondition([System.Windows.Automation.AutomationElement]::ControlTypeProperty, [System.Windows.Automation.ControlType]::TabItem)
239
+ foreach ($tab in $win.FindAll('Descendants', $tabCond)) {
240
+ if (-not ($tab.Current.Name -like "$WEB_TITLE_PREFIX*")) { continue }
241
+ # 命中已打开的 DSH Web 标签页: 切换过去并激活窗口
242
+ ([System.Windows.Automation.SelectionItemPattern]$tab.GetCurrentPattern([System.Windows.Automation.SelectionItemPattern]::Pattern)).Select()
243
+ $hwnd = [IntPtr]$win.Current.NativeWindowHandle
244
+ [DSH.Win32FG]::ShowWindow($hwnd, 9) | Out-Null # SW_RESTORE: 最小化也恢复
245
+ [DSH.Win32FG]::SetForegroundWindow($hwnd) | Out-Null
246
+ Write-Host "[web] 已切换到已打开的 DSH Web 标签页" -ForegroundColor Green
247
+ return
248
+ }
249
+ }
250
+ Write-Host "[web] 未发现已打开的 Web 标签页, 新开" -ForegroundColor DarkGray
251
+ } catch {
252
+ Write-Host "[web] 切换检测不可用($($_.Exception.Message)), 新开" -ForegroundColor DarkGray
253
+ }
254
+ Start-Process $Url
255
+ }
256
+
210
257
  function Show-Status {
211
258
  $pids = @(Get-WebPid)
212
259
  if ($pids.Count -gt 0) {
@@ -195,7 +195,7 @@ $menu.Items.Add((New-Object System.Windows.Forms.ToolStripSeparator)) | Out-Null
195
195
 
196
196
  # ---- Web UI 子菜单 ----
197
197
  $itemDsh = New-SubMenu 'Web UI'
198
- $itemOpen = New-MenuItem '打开 Web UI' { try { Start-Process $URL } catch { Log "打开 Web 失败: $($_.Exception.Message)" } }
198
+ $itemOpen = New-MenuItem '打开 Web UI' { try { Open-DshWeb } catch { Log "打开 Web 失败: $($_.Exception.Message)" } }
199
199
  $itemStart = New-MenuItem '启动 Web UI' { Invoke-DshAction 'start' }
200
200
  $itemStop = New-MenuItem '停止 Web UI' {
201
201
  $r = [System.Windows.Forms.MessageBox]::Show('确定停止 Web UI 服务?Web 界面与当前会话将关闭。', 'DSH 系统托盘', 'YesNo', 'Question', 'Button2')
@@ -336,7 +336,7 @@ $notify.Text = "DSH 托盘 · 检测中 (端口 $PORT)"
336
336
  $notify.ContextMenuStrip = $menu
337
337
  $notify.Visible = $true
338
338
  $notify.add_DoubleClick({
339
- if (Test-Port $PORT) { Start-Process $URL } else { Show-Balloon 'DSH' 'Web UI 未运行,右键选择「启动 Web UI」' }
339
+ if (Test-Port $PORT) { Open-DshWeb } else { Show-Balloon 'DSH' 'Web UI 未运行,右键选择「启动 Web UI」' }
340
340
  })
341
341
 
342
342
  function Show-Balloon([string]$title, [string]$text) {
@@ -119,14 +119,15 @@ if (-not (Test-Path $newInstall)) {
119
119
  }
120
120
 
121
121
  # 3) 运行新包 install.ps1 (重新部署 + 快捷方式, 不启动托盘; -Auto=隐藏窗口非交互)
122
- # v1.0.7: Run-HiddenPwshinstall.ps1 输出含中文, cmd >> 会写 GBK 回读乱码; Out-File 统一 UTF-8
122
+ # v1.0.8: 改用全流合并 *>&12>&1 捕不到 Write-Host 信息流, 中文经隐形控制台编码变 '?';
123
+ # $InformationPreference='Continue' 让信息流进管道, Out-File 统一 UTF-8
123
124
  # v1.0.5: 显式传本机适配值 (取自点源的 dsh-lib, install 不必重新探测; 自定义安装位置必需)
124
125
  $dshRoot = Split-Path $DSH_CMD -Parent
125
126
  $deployLog = Join-Path $LOG_DIR 'dsh-update-deploy.log'
126
127
  Remove-Item $deployLog -Force -ErrorAction SilentlyContinue
127
- $deployPwsh = '-ExecutionPolicy Bypass -Command "$ErrorActionPreference=''Continue''; try { & ''' + $newInstall + ''' -Auto -NoTrayStart' +
128
+ $deployPwsh = '-ExecutionPolicy Bypass -Command "$InformationPreference=''Continue''; $ErrorActionPreference=''Continue''; try { & ''' + $newInstall + ''' -Auto -NoTrayStart' +
128
129
  ' -DshRoot ''' + $dshRoot + ''' -Port ' + $PORT +
129
- ' -NodePath ''' + $NODE + ''' -PwshPath ''' + $PWSH + ''' 2>&1 |' +
130
+ ' -NodePath ''' + $NODE + ''' -PwshPath ''' + $PWSH + ''' *>&1 |' +
130
131
  ' Out-File -FilePath ''' + $deployLog + ''' -Encoding utf8 } catch {' +
131
132
  ' $_ | Out-File -FilePath ''' + $deployLog + ''' -Append -Encoding utf8; exit 1 }; exit 0'
132
133
  $code = Run-HiddenPwsh $PWSH $deployPwsh 120000
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-windows-tray",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "DSH (DeepSeek Harness) Windows 系统托盘: 蓝/灰鲸鱼状态图标 + Web/TUI 一键启停控制。纯 PowerShell + WinForms, 零依赖。",
5
5
  "license": "MIT",
6
6
  "author": "jankin_lv",