dsh-windows-tray 1.0.2 → 1.0.4

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.
@@ -1,116 +1,116 @@
1
- # dsh-update.ps1 —— 托盘自更新执行器 (由托盘菜单「更新到最新版」触发, 独立隐藏进程)
2
- # 流程: npm install -g 最新包 -> 运行新包 install.ps1 (重新部署+改写路径+快捷方式) -> 杀旧托盘 -> 起新托盘
3
- # 失败时旧托盘不受影响 (旧托盘在最后一步才被终止)
4
- param(
5
- [int]$OldPid = 0
6
- )
7
- $ErrorActionPreference = 'Stop'
8
- . (Join-Path $PSScriptRoot 'dsh-lib.ps1')
9
-
10
- $logFile = Join-Path $LOG_DIR 'dsh-tray-actions.log'
11
- function Log([string]$msg) {
12
- Add-Content -Path $logFile -Value ('[{0}] {1}' -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), $msg) -ErrorAction SilentlyContinue
13
- }
14
-
15
- function Find-NpmCmd {
16
- if ($NODE -and (Test-Path $NODE)) {
17
- $p = Join-Path (Split-Path $NODE -Parent) 'npm.cmd'
18
- if (Test-Path $p) { return $p }
19
- }
20
- $c = Get-Command npm.cmd -ErrorAction SilentlyContinue
21
- if ($c) { return $c.Source }
22
- $c2 = Get-Command npm -ErrorAction SilentlyContinue
23
- if ($c2) { return $c2.Source }
24
- return $null
25
- }
26
-
27
- # 隐藏执行 cmd /c (CreateNoWindow: 不弹黑窗), 可选超时
28
- function Run-HiddenCmd([string]$cmdLine, [int]$timeoutMs = 0) {
29
- $psi = New-Object System.Diagnostics.ProcessStartInfo
30
- $psi.FileName = $env:ComSpec
31
- $psi.Arguments = $cmdLine
32
- $psi.UseShellExecute = $false
33
- $psi.CreateNoWindow = $true
34
- $p = [System.Diagnostics.Process]::Start($psi)
35
- if ($timeoutMs -gt 0) {
36
- $p.WaitForExit($timeoutMs) | Out-Null
37
- if (-not $p.HasExited) { $p.Kill(); return -1 }
38
- } else { $p.WaitForExit() }
39
- return $p.ExitCode
40
- }
41
-
42
- # 结果气泡 (临时 NotifyIcon, 更新脚本自身无托盘)
43
- function Show-Balloon([string]$text, [string]$icon = 'Info') {
44
- try {
45
- Add-Type -AssemblyName System.Windows.Forms
46
- Add-Type -AssemblyName System.Drawing
47
- $n = New-Object System.Windows.Forms.NotifyIcon
48
- $n.Icon = [System.Drawing.SystemIcons]::Information
49
- $n.Visible = $true
50
- $n.BalloonTipTitle = 'DSH 系统托盘'
51
- $n.BalloonTipText = $text
52
- $n.BalloonTipIcon = [System.Windows.Forms.ToolTipIcon]::$icon
53
- $n.ShowBalloonTip(5000)
54
- Start-Sleep -Seconds 6
55
- $n.Visible = $false
56
- $n.Dispose()
57
- } catch { }
58
- }
59
-
60
- Log '自更新开始'
61
- $npm = Find-NpmCmd
62
- if (-not $npm) {
63
- Log '自更新失败: npm 未找到'
64
- Show-Balloon '自更新失败:npm 未找到' 'Error'
65
- exit 1
66
- }
67
-
68
- # 1) 安装最新包 (全局)
69
- $code = Run-HiddenCmd ('/c ""' + $npm + '" install -g ' + $TRAY_PKG + ' 2>nul "', 180000)
70
- if ($code -ne 0) {
71
- Log "自更新失败: npm install 退出码 $code"
72
- Show-Balloon '自更新失败:npm install 出错,详见日志' 'Error'
73
- exit 1
74
- }
75
- Log 'npm install -g 完成'
76
-
77
- # 2) 定位新包根目录
78
- $rootTmp = Join-Path $LOG_DIR 'tray-npm-root.txt'
79
- Remove-Item $rootTmp -Force -ErrorAction SilentlyContinue
80
- Run-HiddenCmd ('/c ""' + $npm + '" root -g > "' + $rootTmp + '" 2>nul "') | Out-Null
81
- $globalRoot = ''
82
- if (Test-Path $rootTmp) {
83
- $globalRoot = (Get-Content $rootTmp -Raw).Trim()
84
- Remove-Item $rootTmp -Force -ErrorAction SilentlyContinue
85
- }
86
- $newInstall = Join-Path $globalRoot ($TRAY_PKG + '\install.ps1')
87
- if (-not (Test-Path $newInstall)) {
88
- Log "自更新失败: 未找到新包 $newInstall"
89
- Show-Balloon '自更新失败:未找到新包(npm 全局目录)' 'Error'
90
- exit 1
91
- }
92
-
93
- # 3) 运行新包 install.ps1 (重新部署 + 探测回填 + 快捷方式, 不启动托盘; -Auto=隐藏窗口非交互)
94
- $code = Run-HiddenCmd ('/c ""' + $PWSH + '" -NoProfile -ExecutionPolicy Bypass -File "' + $newInstall + '" -Auto -NoTrayStart 2>nul "', 120000)
95
- if ($code -ne 0) {
96
- Log "自更新失败: install.ps1 退出码 $code"
97
- Show-Balloon '自更新失败:部署出错,详见日志' 'Error'
98
- exit 1
99
- }
100
- Log '新版本部署完成'
101
-
102
- # 4) 杀旧托盘 -> 起新托盘
103
- if ($OldPid -gt 0) {
104
- Stop-Process -Id $OldPid -Force -ErrorAction SilentlyContinue
105
- Log "旧托盘已停止 (PID $OldPid)"
106
- }
107
- Start-Sleep -Milliseconds 500
108
- $newTray = Join-Path $env:USERPROFILE '.dsh\launcher\dsh-tray.ps1'
109
- if (Test-Path $PWSH) {
110
- Start-Process -FilePath $PWSH -ArgumentList @('-NoProfile', '-ExecutionPolicy', 'Bypass', '-WindowStyle', 'Hidden', '-File', $newTray) -WindowStyle Hidden | Out-Null
111
- } else {
112
- Start-Process -FilePath 'powershell.exe' -ArgumentList @('-NoProfile', '-ExecutionPolicy', 'Bypass', '-WindowStyle', 'Hidden', '-File', $newTray) -WindowStyle Hidden | Out-Null
113
- }
114
- Log '新托盘已启动'
115
- Show-Balloon '托盘已更新并自动重启 ✓'
1
+ # dsh-update.ps1 —— 托盘自更新执行器 (由托盘菜单「更新到最新版」触发, 独立隐藏进程)
2
+ # 流程: npm install -g 最新包 -> 运行新包 install.ps1 (重新部署+改写路径+快捷方式) -> 杀旧托盘 -> 起新托盘
3
+ # 失败时旧托盘不受影响 (旧托盘在最后一步才被终止)
4
+ param(
5
+ [int]$OldPid = 0
6
+ )
7
+ $ErrorActionPreference = 'Stop'
8
+ . (Join-Path $PSScriptRoot 'dsh-lib.ps1')
9
+
10
+ $logFile = Join-Path $LOG_DIR 'dsh-tray-actions.log'
11
+ function Log([string]$msg) {
12
+ Add-Content -Path $logFile -Value ('[{0}] {1}' -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), $msg) -ErrorAction SilentlyContinue
13
+ }
14
+
15
+ function Find-NpmCmd {
16
+ if ($NODE -and (Test-Path $NODE)) {
17
+ $p = Join-Path (Split-Path $NODE -Parent) 'npm.cmd'
18
+ if (Test-Path $p) { return $p }
19
+ }
20
+ $c = Get-Command npm.cmd -ErrorAction SilentlyContinue
21
+ if ($c) { return $c.Source }
22
+ $c2 = Get-Command npm -ErrorAction SilentlyContinue
23
+ if ($c2) { return $c2.Source }
24
+ return $null
25
+ }
26
+
27
+ # 隐藏执行 cmd /c (CreateNoWindow: 不弹黑窗), 可选超时
28
+ function Run-HiddenCmd([string]$cmdLine, [int]$timeoutMs = 0) {
29
+ $psi = New-Object System.Diagnostics.ProcessStartInfo
30
+ $psi.FileName = $env:ComSpec
31
+ $psi.Arguments = $cmdLine
32
+ $psi.UseShellExecute = $false
33
+ $psi.CreateNoWindow = $true
34
+ $p = [System.Diagnostics.Process]::Start($psi)
35
+ if ($timeoutMs -gt 0) {
36
+ $p.WaitForExit($timeoutMs) | Out-Null
37
+ if (-not $p.HasExited) { $p.Kill(); return -1 }
38
+ } else { $p.WaitForExit() }
39
+ return $p.ExitCode
40
+ }
41
+
42
+ # 结果气泡 (临时 NotifyIcon, 更新脚本自身无托盘)
43
+ function Show-Balloon([string]$text, [string]$icon = 'Info') {
44
+ try {
45
+ Add-Type -AssemblyName System.Windows.Forms
46
+ Add-Type -AssemblyName System.Drawing
47
+ $n = New-Object System.Windows.Forms.NotifyIcon
48
+ $n.Icon = [System.Drawing.SystemIcons]::Information
49
+ $n.Visible = $true
50
+ $n.BalloonTipTitle = 'DSH 系统托盘'
51
+ $n.BalloonTipText = $text
52
+ $n.BalloonTipIcon = [System.Windows.Forms.ToolTipIcon]::$icon
53
+ $n.ShowBalloonTip(5000)
54
+ Start-Sleep -Seconds 6
55
+ $n.Visible = $false
56
+ $n.Dispose()
57
+ } catch { }
58
+ }
59
+
60
+ Log '自更新开始'
61
+ $npm = Find-NpmCmd
62
+ if (-not $npm) {
63
+ Log '自更新失败: npm 未找到'
64
+ Show-Balloon '自更新失败:npm 未找到' 'Error'
65
+ exit 1
66
+ }
67
+
68
+ # 1) 安装最新包 (全局)
69
+ $code = Run-HiddenCmd ('/c ""' + $npm + '" install -g ' + $TRAY_PKG + ' 2>nul "', 180000)
70
+ if ($code -ne 0) {
71
+ Log "自更新失败: npm install 退出码 $code"
72
+ Show-Balloon '自更新失败:npm install 出错,详见日志' 'Error'
73
+ exit 1
74
+ }
75
+ Log 'npm install -g 完成'
76
+
77
+ # 2) 定位新包根目录
78
+ $rootTmp = Join-Path $LOG_DIR 'tray-npm-root.txt'
79
+ Remove-Item $rootTmp -Force -ErrorAction SilentlyContinue
80
+ Run-HiddenCmd ('/c ""' + $npm + '" root -g > "' + $rootTmp + '" 2>nul "') | Out-Null
81
+ $globalRoot = ''
82
+ if (Test-Path $rootTmp) {
83
+ $globalRoot = (Get-Content $rootTmp -Raw).Trim()
84
+ Remove-Item $rootTmp -Force -ErrorAction SilentlyContinue
85
+ }
86
+ $newInstall = Join-Path $globalRoot ($TRAY_PKG + '\install.ps1')
87
+ if (-not (Test-Path $newInstall)) {
88
+ Log "自更新失败: 未找到新包 $newInstall"
89
+ Show-Balloon '自更新失败:未找到新包(npm 全局目录)' 'Error'
90
+ exit 1
91
+ }
92
+
93
+ # 3) 运行新包 install.ps1 (重新部署 + 探测回填 + 快捷方式, 不启动托盘; -Auto=隐藏窗口非交互)
94
+ $code = Run-HiddenCmd ('/c ""' + $PWSH + '" -NoProfile -ExecutionPolicy Bypass -File "' + $newInstall + '" -Auto -NoTrayStart 2>nul "', 120000)
95
+ if ($code -ne 0) {
96
+ Log "自更新失败: install.ps1 退出码 $code"
97
+ Show-Balloon '自更新失败:部署出错,详见日志' 'Error'
98
+ exit 1
99
+ }
100
+ Log '新版本部署完成'
101
+
102
+ # 4) 杀旧托盘 -> 起新托盘
103
+ if ($OldPid -gt 0) {
104
+ Stop-Process -Id $OldPid -Force -ErrorAction SilentlyContinue
105
+ Log "旧托盘已停止 (PID $OldPid)"
106
+ }
107
+ Start-Sleep -Milliseconds 500
108
+ $newTray = Join-Path $env:USERPROFILE '.dsh\launcher\dsh-tray.ps1'
109
+ if (Test-Path $PWSH) {
110
+ Start-Process -FilePath $PWSH -ArgumentList @('-NoProfile', '-ExecutionPolicy', 'Bypass', '-WindowStyle', 'Hidden', '-File', $newTray) -WindowStyle Hidden | Out-Null
111
+ } else {
112
+ Start-Process -FilePath 'powershell.exe' -ArgumentList @('-NoProfile', '-ExecutionPolicy', 'Bypass', '-WindowStyle', 'Hidden', '-File', $newTray) -WindowStyle Hidden | Out-Null
113
+ }
114
+ Log '新托盘已启动'
115
+ Show-Balloon '托盘已更新并自动重启 ✓'
116
116
  exit 0
package/package.json CHANGED
@@ -1,36 +1,39 @@
1
- {
2
- "name": "dsh-windows-tray",
3
- "version": "1.0.2",
4
- "description": "DSH (DeepSeek Harness) Windows 系统托盘: 蓝/灰鲸鱼状态图标 + Web/TUI 一键启停控制。纯 PowerShell + WinForms, 零依赖。",
5
- "license": "MIT",
6
- "author": "jankin_lv",
7
- "keywords": [
8
- "dsh",
9
- "deepseek",
10
- "harness",
11
- "tray",
12
- "notifyicon",
13
- "windows",
14
- "powershell",
15
- "system-tray"
16
- ],
17
- "os": [
18
- "win32"
19
- ],
20
- "engines": {
21
- "node": ">=18"
22
- },
23
- "files": [
24
- "launcher/",
25
- "build/",
26
- "docs/",
27
- "bin/",
28
- "install.ps1",
29
- "README.md",
30
- "LICENSE"
31
- ],
32
- "bin": {
33
- "dsh-tray": "bin/dsh-tray.js"
34
- },
35
- "private": false
36
- }
1
+ {
2
+ "name": "dsh-windows-tray",
3
+ "version": "1.0.4",
4
+ "description": "DSH (DeepSeek Harness) Windows 系统托盘: 蓝/灰鲸鱼状态图标 + Web/TUI 一键启停控制。纯 PowerShell + WinForms, 零依赖。",
5
+ "license": "MIT",
6
+ "author": "jankin_lv",
7
+ "keywords": [
8
+ "dsh",
9
+ "deepseek",
10
+ "harness",
11
+ "tray",
12
+ "notifyicon",
13
+ "windows",
14
+ "powershell",
15
+ "system-tray"
16
+ ],
17
+ "os": [
18
+ "win32"
19
+ ],
20
+ "engines": {
21
+ "node": ">=18"
22
+ },
23
+ "files": [
24
+ "launcher/",
25
+ "build/",
26
+ "docs/",
27
+ "bin/",
28
+ "install.ps1",
29
+ "README.md",
30
+ "LICENSE"
31
+ ],
32
+ "bin": {
33
+ "dsh-tray": "bin/dsh-tray.js"
34
+ },
35
+ "scripts": {
36
+ "prepublishOnly": "node ../../scripts/publish-check.mjs"
37
+ },
38
+ "private": false
39
+ }
@@ -1,4 +0,0 @@
1
- @echo off
2
- chcp 65001 > nul
3
- powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0bh-menu.ps1"
4
- pause
@@ -1,56 +0,0 @@
1
- # dsh 黑洞模拟器启动器 —— 网页版交互黑洞(oseiskar/black-hole)
2
- # 用法: 双击 bh-menu.bat 或 powershell -File bh-menu.ps1 -Cmd start|stop|status
3
- param([string]$Cmd)
4
- $ErrorActionPreference = 'Stop'
5
- chcp 65001 > $null
6
-
7
- $PORT = 8137
8
- $URL = 'http://127.0.0.1:8137'
9
- $DIR = "$env:USERPROFILE\.dsh\gen-wallpaper\bh-shader"
10
-
11
- function Test-Port([int]$port) {
12
- $c = New-Object System.Net.Sockets.TcpClient
13
- try { if ($c.BeginConnect('127.0.0.1', $port, $null, $null).AsyncWaitHandle.WaitOne(500) -and $c.Connected) { return $true } } catch {}
14
- finally { $c.Close() }
15
- return $false
16
- }
17
-
18
- function Start-BH {
19
- if (Test-Port $PORT) { Write-Output "[bh] 服务已在运行: $URL"; Start-Process $URL; return }
20
- Start-Process node -ArgumentList 'serve.mjs' -WorkingDirectory $DIR -WindowStyle Hidden
21
- Start-Sleep -Seconds 3
22
- if (Test-Port $PORT) { Write-Output "[bh] 启动成功: $URL"; Start-Process $URL }
23
- else { Write-Output "[bh] 启动失败, 请手工运行: cd $DIR; node serve.mjs" }
24
- }
25
-
26
- function Stop-BH {
27
- $pids = @((Get-NetTCPConnection -LocalPort $PORT -State Listen -ErrorAction SilentlyContinue).OwningProcess | Select-Object -Unique)
28
- if ($pids.Count -eq 0) { Write-Output '[bh] 服务未运行'; return }
29
- foreach ($p in $pids) { Write-Output "[bh] 停止进程 $p"; & taskkill /PID $p /F 2>$null | Out-Null }
30
- Write-Output '[bh] 已停止'
31
- }
32
-
33
- if ($Cmd) {
34
- switch ($Cmd.ToLower()) {
35
- 'start' { Start-BH }
36
- 'stop' { Stop-BH }
37
- 'status'{ if (Test-Port $PORT) { Write-Output "[bh] 运行中: $URL" } else { Write-Output '[bh] 未运行' } }
38
- default { Write-Output '用法: bh-menu.ps1 -Cmd start|stop|status' }
39
- }
40
- exit
41
- }
42
- while ($true) {
43
- Write-Output ''
44
- Write-Output '======== 黑洞模拟器 ========'
45
- if (Test-Port $PORT) { Write-Output '状态: 运行中' } else { Write-Output '状态: 未运行' }
46
- Write-Output '[1] 启动并打开浏览器'
47
- Write-Output '[2] 停止'
48
- Write-Output '[0] 退出'
49
- $choice = Read-Host '请选择'
50
- switch ($choice) {
51
- '1' { Start-BH }
52
- '2' { Stop-BH }
53
- '0' { exit }
54
- default { Write-Output '无效选择' }
55
- }
56
- }
@@ -1,4 +0,0 @@
1
- @echo off
2
- chcp 65001 > nul
3
- powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0dsh-all-menu.ps1"
4
- pause
@@ -1,106 +0,0 @@
1
- # dsh 一体化控制台 —— 同时管理 dsh web (3080) 和黑洞模拟器 (8137)
2
- # 用法: 双击 dsh-一体化菜单.lnk / dsh-all-menu.bat 进入交互菜单
3
- # 命令行: dsh-all-menu.ps1 -Cmd all-start|all-stop|dsh-start|dsh-stop|bh-start|bh-stop|status|open
4
- param([string]$Cmd)
5
- $ErrorActionPreference = 'Stop'
6
- chcp 65001 > $null
7
-
8
- $DshMenu = "$PSScriptRoot\dsh-menu.ps1"
9
- $BhMenu = "$PSScriptRoot\bh-menu.ps1"
10
- $DshUrl = 'http://127.0.0.1:3080'
11
- $BhUrl = 'http://127.0.0.1:8137'
12
-
13
- function Test-Port([int]$port) {
14
- $c = New-Object System.Net.Sockets.TcpClient
15
- try { if ($c.BeginConnect('127.0.0.1', $port, $null, $null).AsyncWaitHandle.WaitOne(500) -and $c.Connected) { return $true } } catch {}
16
- finally { $c.Close() }
17
- return $false
18
- }
19
-
20
- function StatusLine {
21
- $d = if (Test-Port 3080) { "运行中: $DshUrl" } else { '未运行' }
22
- $b = if (Test-Port 8137) { "运行中: $BhUrl" } else { '未运行' }
23
- Write-Host " [dsh] $d" -ForegroundColor $(if (Test-Port 3080) { 'Green' } else { 'Red' })
24
- Write-Host " [bh ] $b" -ForegroundColor $(if (Test-Port 8137) { 'Green' } else { 'Red' })
25
- }
26
-
27
- function All-Start {
28
- Write-Host '启动 dsh web ...' -ForegroundColor Cyan
29
- & powershell -NoProfile -ExecutionPolicy Bypass -File $DshMenu -Cmd start | Out-Host
30
- Write-Host '启动 黑洞模拟器 ...' -ForegroundColor Cyan
31
- & powershell -NoProfile -ExecutionPolicy Bypass -File $BhMenu -Cmd start | Out-Host
32
- }
33
- function All-Stop {
34
- Write-Host '停止 dsh web ...' -ForegroundColor Yellow
35
- & powershell -NoProfile -ExecutionPolicy Bypass -File $DshMenu -Cmd stop | Out-Host
36
- Write-Host '停止 黑洞模拟器 ...' -ForegroundColor Yellow
37
- & powershell -NoProfile -ExecutionPolicy Bypass -File $BhMenu -Cmd stop | Out-Host
38
- }
39
- function Pause-Back { Read-Host '按回车键返回菜单' | Out-Null }
40
-
41
- function Show-Detail {
42
- Write-Host ' ── dsh web ──' -ForegroundColor Cyan
43
- if (Test-Port 3080) {
44
- $p = (Get-NetTCPConnection -LocalPort 3080 -State Listen | Select-Object -First 1).OwningProcess
45
- Write-Host " 状态: 运行中 PID: $p" -ForegroundColor Green
46
- Write-Host " 地址: $DshUrl" -ForegroundColor White
47
- } else { Write-Host ' 状态: 未运行' -ForegroundColor Red }
48
- Write-Host ' ── 黑洞模拟器 ──' -ForegroundColor Cyan
49
- if (Test-Port 8137) {
50
- $p = (Get-NetTCPConnection -LocalPort 8137 -State Listen | Select-Object -First 1).OwningProcess
51
- Write-Host " 状态: 运行中 PID: $p" -ForegroundColor Green
52
- Write-Host " 地址: $BhUrl" -ForegroundColor White
53
- } else { Write-Host ' 状态: 未运行' -ForegroundColor Red }
54
- }
55
-
56
- if ($Cmd) {
57
- switch ($Cmd.ToLower()) {
58
- 'all-start' { All-Start }
59
- 'all-stop' { All-Stop }
60
- 'dsh-start' { & powershell -NoProfile -ExecutionPolicy Bypass -File $DshMenu -Cmd start | Out-Host }
61
- 'dsh-stop' { & powershell -NoProfile -ExecutionPolicy Bypass -File $DshMenu -Cmd stop | Out-Host }
62
- 'bh-start' { & powershell -NoProfile -ExecutionPolicy Bypass -File $BhMenu -Cmd start | Out-Host }
63
- 'bh-stop' { & powershell -NoProfile -ExecutionPolicy Bypass -File $BhMenu -Cmd stop | Out-Host }
64
- 'status' { StatusLine }
65
- 'open' { if (Test-Port 3080) { Start-Process $DshUrl } else { Write-Host '[dsh] 未运行' -ForegroundColor Red }
66
- if (Test-Port 8137) { Start-Process $BhUrl } else { Write-Host '[bh] 未运行' -ForegroundColor Red } }
67
- default { Write-Output '用法: dsh-all-menu.ps1 -Cmd all-start|all-stop|dsh-start|dsh-stop|bh-start|bh-stop|status|open' }
68
- }
69
- exit
70
- }
71
-
72
- while ($true) {
73
- Clear-Host
74
- Write-Host ''
75
- Write-Host ' ╔═══════════════════════════════════════╗' -ForegroundColor Cyan
76
- Write-Host ' ║ dsh 一体化控制台 v1 ║' -ForegroundColor Cyan
77
- Write-Host ' ╚═══════════════════════════════════════╝' -ForegroundColor Cyan
78
- Write-Host ''
79
- StatusLine
80
- Write-Host ''
81
- Write-Host ' [1] 全部启动 (dsh + 黑洞) 并打开浏览器' -ForegroundColor White
82
- Write-Host ' [2] 全部停止' -ForegroundColor White
83
- Write-Host ' [3] 只启动 dsh [4] 只停止 dsh' -ForegroundColor White
84
- Write-Host ' [5] 只启动黑洞 [6] 只停止黑洞' -ForegroundColor White
85
- Write-Host ' [7] 服务详情 (PID/端口)' -ForegroundColor White
86
- Write-Host ' [8] 打开 dsh 页面 [9] 打开黑洞页面' -ForegroundColor White
87
- Write-Host ' [0] 退出' -ForegroundColor White
88
- Write-Host ''
89
- $choice = Read-Host ' 请选择'
90
- Write-Host ''
91
- switch ($choice) {
92
- '1' { All-Start; Pause-Back }
93
- '2' { All-Stop; Pause-Back }
94
- '3' { & powershell -NoProfile -ExecutionPolicy Bypass -File $DshMenu -Cmd start | Out-Host; Pause-Back }
95
- '4' { & powershell -NoProfile -ExecutionPolicy Bypass -File $DshMenu -Cmd stop | Out-Host; Pause-Back }
96
- '5' { & powershell -NoProfile -ExecutionPolicy Bypass -File $BhMenu -Cmd start | Out-Host; Pause-Back }
97
- '6' { & powershell -NoProfile -ExecutionPolicy Bypass -File $BhMenu -Cmd stop | Out-Host; Pause-Back }
98
- '7' { Show-Detail; Pause-Back }
99
- '8' { if (Test-Port 3080) { Start-Process $DshUrl } else { Write-Host ' [dsh] 未运行, 请先启动' -ForegroundColor Red }
100
- Pause-Back }
101
- '9' { if (Test-Port 8137) { Start-Process $BhUrl } else { Write-Host ' [bh] 未运行, 请先启动' -ForegroundColor Red }
102
- Pause-Back }
103
- '0' { Write-Host ' 再见!' -ForegroundColor Cyan; exit }
104
- default { Write-Host ' 无效选择, 请重试' -ForegroundColor Red; Start-Sleep -Milliseconds 800 }
105
- }
106
- }