dsh-windows-tray 1.0.2 → 1.0.3
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/LICENSE +21 -21
- package/README.md +146 -146
- package/bin/dsh-tray.js +100 -100
- package/build/build-tray-icons.ps1 +98 -98
- package/build/whale-render.html +8 -8
- package/docs/tray-dev-archive.md +57 -57
- package/install.ps1 +230 -184
- package/launcher/bh-menu.ps1 +56 -56
- package/launcher/dsh-actions.ps1 +50 -50
- package/launcher/dsh-all-menu.ps1 +106 -106
- package/launcher/dsh-control.ps1 +40 -40
- package/launcher/dsh-lib.ps1 +1 -1
- package/launcher/dsh-menu.ps1 +93 -93
- package/launcher/dsh-tray.bat +10 -10
- package/launcher/dsh-tray.ps1 +429 -418
- package/launcher/dsh-update.ps1 +115 -115
- package/package.json +36 -36
package/launcher/dsh-actions.ps1
CHANGED
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
# dsh-actions.ps1 —— 托盘菜单动作执行器 (由 dsh-tray.ps1 以独立隐藏进程拉起)
|
|
2
|
-
# 用法: pwsh -NoProfile -File dsh-actions.ps1 -Action start|stop|restart|tui-start|tui-stop
|
|
3
|
-
# 动作在独立进程执行, 托盘 UI 线程保持响应; 日志写入 ~/.dsh/logs/dsh-tray-actions.log
|
|
4
|
-
param(
|
|
5
|
-
[Parameter(Mandatory = $true)]
|
|
6
|
-
[ValidateSet('start', 'stop', 'restart', 'tui-start', 'tui-stop')]
|
|
7
|
-
[string]$Action
|
|
8
|
-
)
|
|
9
|
-
$ErrorActionPreference = 'Stop'
|
|
10
|
-
|
|
11
|
-
. (Join-Path $PSScriptRoot 'dsh-lib.ps1')
|
|
12
|
-
|
|
13
|
-
$logFile = Join-Path $LOG_DIR 'dsh-tray-actions.log'
|
|
14
|
-
function Log([string]$msg) {
|
|
15
|
-
$line = ('[{0}] {1}' -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), $msg)
|
|
16
|
-
Add-Content -Path $logFile -Value $line -ErrorAction SilentlyContinue
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
try {
|
|
20
|
-
switch ($Action) {
|
|
21
|
-
'start' {
|
|
22
|
-
Log '启动 DSH (来自系统托盘)'
|
|
23
|
-
Start-Dsh -OpenBrowser:$false
|
|
24
|
-
Log '启动动作完成'
|
|
25
|
-
}
|
|
26
|
-
'stop' {
|
|
27
|
-
Log '停止 DSH (来自系统托盘)'
|
|
28
|
-
Stop-Dsh
|
|
29
|
-
Log '停止动作完成'
|
|
30
|
-
}
|
|
31
|
-
'restart' {
|
|
32
|
-
Log '重启 DSH (来自系统托盘)'
|
|
33
|
-
Restart-Dsh
|
|
34
|
-
Log '重启动作完成'
|
|
35
|
-
}
|
|
36
|
-
'tui-start' {
|
|
37
|
-
Log '启动 TUI (来自系统托盘)'
|
|
38
|
-
Start-Tui
|
|
39
|
-
Log 'TUI 启动动作完成'
|
|
40
|
-
}
|
|
41
|
-
'tui-stop' {
|
|
42
|
-
Log '停止 TUI (来自系统托盘)'
|
|
43
|
-
Stop-Tui
|
|
44
|
-
Log 'TUI 停止动作完成'
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
} catch {
|
|
48
|
-
Log ("动作 {0} 失败: {1}" -f $Action, $_.Exception.Message)
|
|
49
|
-
exit 1
|
|
50
|
-
}
|
|
1
|
+
# dsh-actions.ps1 —— 托盘菜单动作执行器 (由 dsh-tray.ps1 以独立隐藏进程拉起)
|
|
2
|
+
# 用法: pwsh -NoProfile -File dsh-actions.ps1 -Action start|stop|restart|tui-start|tui-stop
|
|
3
|
+
# 动作在独立进程执行, 托盘 UI 线程保持响应; 日志写入 ~/.dsh/logs/dsh-tray-actions.log
|
|
4
|
+
param(
|
|
5
|
+
[Parameter(Mandatory = $true)]
|
|
6
|
+
[ValidateSet('start', 'stop', 'restart', 'tui-start', 'tui-stop')]
|
|
7
|
+
[string]$Action
|
|
8
|
+
)
|
|
9
|
+
$ErrorActionPreference = 'Stop'
|
|
10
|
+
|
|
11
|
+
. (Join-Path $PSScriptRoot 'dsh-lib.ps1')
|
|
12
|
+
|
|
13
|
+
$logFile = Join-Path $LOG_DIR 'dsh-tray-actions.log'
|
|
14
|
+
function Log([string]$msg) {
|
|
15
|
+
$line = ('[{0}] {1}' -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), $msg)
|
|
16
|
+
Add-Content -Path $logFile -Value $line -ErrorAction SilentlyContinue
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
switch ($Action) {
|
|
21
|
+
'start' {
|
|
22
|
+
Log '启动 DSH (来自系统托盘)'
|
|
23
|
+
Start-Dsh -OpenBrowser:$false
|
|
24
|
+
Log '启动动作完成'
|
|
25
|
+
}
|
|
26
|
+
'stop' {
|
|
27
|
+
Log '停止 DSH (来自系统托盘)'
|
|
28
|
+
Stop-Dsh
|
|
29
|
+
Log '停止动作完成'
|
|
30
|
+
}
|
|
31
|
+
'restart' {
|
|
32
|
+
Log '重启 DSH (来自系统托盘)'
|
|
33
|
+
Restart-Dsh
|
|
34
|
+
Log '重启动作完成'
|
|
35
|
+
}
|
|
36
|
+
'tui-start' {
|
|
37
|
+
Log '启动 TUI (来自系统托盘)'
|
|
38
|
+
Start-Tui
|
|
39
|
+
Log 'TUI 启动动作完成'
|
|
40
|
+
}
|
|
41
|
+
'tui-stop' {
|
|
42
|
+
Log '停止 TUI (来自系统托盘)'
|
|
43
|
+
Stop-Tui
|
|
44
|
+
Log 'TUI 停止动作完成'
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
} catch {
|
|
48
|
+
Log ("动作 {0} 失败: {1}" -f $Action, $_.Exception.Message)
|
|
49
|
+
exit 1
|
|
50
|
+
}
|
|
@@ -1,106 +1,106 @@
|
|
|
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
|
-
}
|
|
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
|
+
}
|
package/launcher/dsh-control.ps1
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
# DSH 控制台 —— 启动/重启 Web + 启动 TUI + 状态查看 + 系统托盘
|
|
2
|
-
# 部署:2026-08-26;双击桌面「DSH 控制台」或 dsh-control.bat
|
|
3
|
-
# 坑:本脚本由用户独立窗口运行(非 web 子进程),杀/重启 web 安全(PITFALLS §12.2)
|
|
4
|
-
# 2026-08-28: 启动/停止/重启/托盘逻辑抽到 dsh-lib.ps1(与系统托盘共享同一份代码)
|
|
5
|
-
$ErrorActionPreference = 'Stop'
|
|
6
|
-
chcp 65001 > $null
|
|
7
|
-
|
|
8
|
-
. (Join-Path $PSScriptRoot 'dsh-lib.ps1')
|
|
9
|
-
|
|
10
|
-
while ($true) {
|
|
11
|
-
Clear-Host
|
|
12
|
-
Write-Host ''
|
|
13
|
-
Write-Host ' ┌──────────────────────────────┐'
|
|
14
|
-
Write-Host ' │ DSH 控制台 │'
|
|
15
|
-
Write-Host ' ├──────────────────────────────┤'
|
|
16
|
-
Write-Host ' │ 1) 启动 / 打开 Web (3088) │'
|
|
17
|
-
Write-Host ' │ 2) 重启 Web │'
|
|
18
|
-
Write-Host ' │ 3) 启动 TUI(新终端窗口) │'
|
|
19
|
-
Write-Host ' │ 4) 查看状态 │'
|
|
20
|
-
Write-Host ' │ 5) 启动系统托盘 │'
|
|
21
|
-
Write-Host ' │ 0) 退出 │'
|
|
22
|
-
Write-Host ' └──────────────────────────────┘'
|
|
23
|
-
$c = Read-Host ' 请选择'
|
|
24
|
-
switch ($c) {
|
|
25
|
-
'1' { Start-Dsh }
|
|
26
|
-
'2' { Restart-Dsh }
|
|
27
|
-
'3' { Start-Tui }
|
|
28
|
-
'4' { Show-Status }
|
|
29
|
-
'5' {
|
|
30
|
-
if (Ensure-DshTray) {
|
|
31
|
-
Write-Host '[tray] 系统托盘已在运行(蓝鲸=运行中 / 灰鲸=未运行,右键可控制)' -ForegroundColor Green
|
|
32
|
-
} else {
|
|
33
|
-
Write-Host '[tray] 系统托盘已启动(蓝鲸=运行中 / 灰鲸=未运行,右键可控制)' -ForegroundColor Green
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
'0' { Write-Host ' 再见!'; break }
|
|
37
|
-
default { Write-Host " 无效选择: $c" -ForegroundColor Red }
|
|
38
|
-
}
|
|
39
|
-
if ($c -ne '0') { Write-Host ''; Read-Host ' 按回车返回菜单' }
|
|
40
|
-
}
|
|
1
|
+
# DSH 控制台 —— 启动/重启 Web + 启动 TUI + 状态查看 + 系统托盘
|
|
2
|
+
# 部署:2026-08-26;双击桌面「DSH 控制台」或 dsh-control.bat
|
|
3
|
+
# 坑:本脚本由用户独立窗口运行(非 web 子进程),杀/重启 web 安全(PITFALLS §12.2)
|
|
4
|
+
# 2026-08-28: 启动/停止/重启/托盘逻辑抽到 dsh-lib.ps1(与系统托盘共享同一份代码)
|
|
5
|
+
$ErrorActionPreference = 'Stop'
|
|
6
|
+
chcp 65001 > $null
|
|
7
|
+
|
|
8
|
+
. (Join-Path $PSScriptRoot 'dsh-lib.ps1')
|
|
9
|
+
|
|
10
|
+
while ($true) {
|
|
11
|
+
Clear-Host
|
|
12
|
+
Write-Host ''
|
|
13
|
+
Write-Host ' ┌──────────────────────────────┐'
|
|
14
|
+
Write-Host ' │ DSH 控制台 │'
|
|
15
|
+
Write-Host ' ├──────────────────────────────┤'
|
|
16
|
+
Write-Host ' │ 1) 启动 / 打开 Web (3088) │'
|
|
17
|
+
Write-Host ' │ 2) 重启 Web │'
|
|
18
|
+
Write-Host ' │ 3) 启动 TUI(新终端窗口) │'
|
|
19
|
+
Write-Host ' │ 4) 查看状态 │'
|
|
20
|
+
Write-Host ' │ 5) 启动系统托盘 │'
|
|
21
|
+
Write-Host ' │ 0) 退出 │'
|
|
22
|
+
Write-Host ' └──────────────────────────────┘'
|
|
23
|
+
$c = Read-Host ' 请选择'
|
|
24
|
+
switch ($c) {
|
|
25
|
+
'1' { Start-Dsh }
|
|
26
|
+
'2' { Restart-Dsh }
|
|
27
|
+
'3' { Start-Tui }
|
|
28
|
+
'4' { Show-Status }
|
|
29
|
+
'5' {
|
|
30
|
+
if (Ensure-DshTray) {
|
|
31
|
+
Write-Host '[tray] 系统托盘已在运行(蓝鲸=运行中 / 灰鲸=未运行,右键可控制)' -ForegroundColor Green
|
|
32
|
+
} else {
|
|
33
|
+
Write-Host '[tray] 系统托盘已启动(蓝鲸=运行中 / 灰鲸=未运行,右键可控制)' -ForegroundColor Green
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
'0' { Write-Host ' 再见!'; break }
|
|
37
|
+
default { Write-Host " 无效选择: $c" -ForegroundColor Red }
|
|
38
|
+
}
|
|
39
|
+
if ($c -ne '0') { Write-Host ''; Read-Host ' 按回车返回菜单' }
|
|
40
|
+
}
|
package/launcher/dsh-lib.ps1
CHANGED
|
@@ -12,7 +12,7 @@ $URL = "http://127.0.0.1:$PORT"
|
|
|
12
12
|
$LOG_DIR = "$env:USERPROFILE\.dsh\logs"
|
|
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.
|
|
15
|
+
$TRAY_VERSION = '1.0.3' # 托盘版本 (与 npm 包版本同步, 用于日志/排查)
|
|
16
16
|
$TRAY_PKG = 'dsh-windows-tray' # npm 包名 (托盘自更新)
|
|
17
17
|
$TRAY_SCRIPT = Join-Path $PSScriptRoot 'dsh-tray.ps1'
|
|
18
18
|
|
package/launcher/dsh-menu.ps1
CHANGED
|
@@ -1,93 +1,93 @@
|
|
|
1
|
-
# dsh (DeepSeek Harness) 启动器 —— 公司机部署 2026-08-14
|
|
2
|
-
# 用法:
|
|
3
|
-
# 交互菜单: 双击 dsh-menu.bat
|
|
4
|
-
# 非交互: dsh-menu.ps1 -Cmd start|stop|status
|
|
5
|
-
# 坑: 不要在本脚本内对 Start-Process 用 -RedirectStandardOutput
|
|
6
|
-
# (父进程 stdout 被重定向时挂起, 见 LEARNED #53)
|
|
7
|
-
param(
|
|
8
|
-
[string]$Cmd
|
|
9
|
-
)
|
|
10
|
-
$ErrorActionPreference = 'Stop'
|
|
11
|
-
|
|
12
|
-
$DSH_CMD = 'D:\Program Files (x86)\dsh\dsh.cmd'
|
|
13
|
-
$PORT = 3080
|
|
14
|
-
$URL = 'http://127.0.0.1:3080'
|
|
15
|
-
|
|
16
|
-
function Test-Port([int]$port) {
|
|
17
|
-
$client = New-Object System.Net.Sockets.TcpClient
|
|
18
|
-
try {
|
|
19
|
-
$async = $client.BeginConnect('127.0.0.1', $port, $null, $null)
|
|
20
|
-
if ($async.AsyncWaitHandle.WaitOne(500) -and $client.Connected) { return $true }
|
|
21
|
-
return $false
|
|
22
|
-
} catch { return $false }
|
|
23
|
-
finally { $client.Close() }
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function Start-Dsh {
|
|
27
|
-
if (Test-Port $PORT) {
|
|
28
|
-
Write-Output "[dsh] 端口 $PORT 已监听, 服务已在运行, 不重复启动"
|
|
29
|
-
return
|
|
30
|
-
}
|
|
31
|
-
Start-Process -FilePath $DSH_CMD -ArgumentList 'web' -WindowStyle Hidden
|
|
32
|
-
Start-Sleep -Seconds 6
|
|
33
|
-
if (Test-Port $PORT) {
|
|
34
|
-
Write-Output "[dsh] 启动成功: $URL"
|
|
35
|
-
} else {
|
|
36
|
-
Start-Sleep -Seconds 5
|
|
37
|
-
if (Test-Port $PORT) {
|
|
38
|
-
Write-Output "[dsh] 启动成功: $URL"
|
|
39
|
-
} else {
|
|
40
|
-
Write-Output "[dsh] 启动失败: 端口 $PORT 未监听, 请手工运行 dsh web 查看报错"
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function Stop-Dsh {
|
|
46
|
-
$pids = @((Get-NetTCPConnection -LocalPort $PORT -State Listen -ErrorAction SilentlyContinue).OwningProcess | Select-Object -Unique)
|
|
47
|
-
if ($pids.Count -eq 0) {
|
|
48
|
-
Write-Output '[dsh] 服务未在运行'
|
|
49
|
-
return
|
|
50
|
-
}
|
|
51
|
-
foreach ($p in $pids) {
|
|
52
|
-
Write-Output "[dsh] 停止进程 $p"
|
|
53
|
-
& taskkill /PID $p /T /F 2>$null | Out-Null
|
|
54
|
-
}
|
|
55
|
-
Start-Sleep -Seconds 2
|
|
56
|
-
if (Test-Port $PORT) { Write-Output '[dsh] 停止失败: 端口仍在监听' }
|
|
57
|
-
else { Write-Output '[dsh] 已停止' }
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function Show-Status {
|
|
61
|
-
if (Test-Port $PORT) { Write-Output "[dsh] 运行中: $URL" }
|
|
62
|
-
else { Write-Output '[dsh] 未运行' }
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
# ---------- 非交互模式 ----------
|
|
66
|
-
if ($Cmd) {
|
|
67
|
-
switch ($Cmd.ToLower()) {
|
|
68
|
-
'start' { Start-Dsh }
|
|
69
|
-
'stop' { Stop-Dsh }
|
|
70
|
-
'status' { Show-Status }
|
|
71
|
-
default { Write-Output '用法: dsh-menu.ps1 -Cmd start|stop|status' }
|
|
72
|
-
}
|
|
73
|
-
exit
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
# ---------- 交互菜单 ----------
|
|
77
|
-
while ($true) {
|
|
78
|
-
Write-Output ''
|
|
79
|
-
Write-Output '======== dsh 启动器 ========'
|
|
80
|
-
Show-Status
|
|
81
|
-
Write-Output '[1] 启动并打开浏览器'
|
|
82
|
-
Write-Output '[2] 停止'
|
|
83
|
-
Write-Output '[3] 状态'
|
|
84
|
-
Write-Output '[0] 退出'
|
|
85
|
-
$choice = Read-Host '请选择'
|
|
86
|
-
switch ($choice) {
|
|
87
|
-
'1' { Start-Dsh; Start-Process $URL; }
|
|
88
|
-
'2' { Stop-Dsh }
|
|
89
|
-
'3' { Show-Status }
|
|
90
|
-
'0' { exit }
|
|
91
|
-
default { Write-Output '无效选择' }
|
|
92
|
-
}
|
|
93
|
-
}
|
|
1
|
+
# dsh (DeepSeek Harness) 启动器 —— 公司机部署 2026-08-14
|
|
2
|
+
# 用法:
|
|
3
|
+
# 交互菜单: 双击 dsh-menu.bat
|
|
4
|
+
# 非交互: dsh-menu.ps1 -Cmd start|stop|status
|
|
5
|
+
# 坑: 不要在本脚本内对 Start-Process 用 -RedirectStandardOutput
|
|
6
|
+
# (父进程 stdout 被重定向时挂起, 见 LEARNED #53)
|
|
7
|
+
param(
|
|
8
|
+
[string]$Cmd
|
|
9
|
+
)
|
|
10
|
+
$ErrorActionPreference = 'Stop'
|
|
11
|
+
|
|
12
|
+
$DSH_CMD = 'D:\Program Files (x86)\dsh\dsh.cmd'
|
|
13
|
+
$PORT = 3080
|
|
14
|
+
$URL = 'http://127.0.0.1:3080'
|
|
15
|
+
|
|
16
|
+
function Test-Port([int]$port) {
|
|
17
|
+
$client = New-Object System.Net.Sockets.TcpClient
|
|
18
|
+
try {
|
|
19
|
+
$async = $client.BeginConnect('127.0.0.1', $port, $null, $null)
|
|
20
|
+
if ($async.AsyncWaitHandle.WaitOne(500) -and $client.Connected) { return $true }
|
|
21
|
+
return $false
|
|
22
|
+
} catch { return $false }
|
|
23
|
+
finally { $client.Close() }
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function Start-Dsh {
|
|
27
|
+
if (Test-Port $PORT) {
|
|
28
|
+
Write-Output "[dsh] 端口 $PORT 已监听, 服务已在运行, 不重复启动"
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
Start-Process -FilePath $DSH_CMD -ArgumentList 'web' -WindowStyle Hidden
|
|
32
|
+
Start-Sleep -Seconds 6
|
|
33
|
+
if (Test-Port $PORT) {
|
|
34
|
+
Write-Output "[dsh] 启动成功: $URL"
|
|
35
|
+
} else {
|
|
36
|
+
Start-Sleep -Seconds 5
|
|
37
|
+
if (Test-Port $PORT) {
|
|
38
|
+
Write-Output "[dsh] 启动成功: $URL"
|
|
39
|
+
} else {
|
|
40
|
+
Write-Output "[dsh] 启动失败: 端口 $PORT 未监听, 请手工运行 dsh web 查看报错"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function Stop-Dsh {
|
|
46
|
+
$pids = @((Get-NetTCPConnection -LocalPort $PORT -State Listen -ErrorAction SilentlyContinue).OwningProcess | Select-Object -Unique)
|
|
47
|
+
if ($pids.Count -eq 0) {
|
|
48
|
+
Write-Output '[dsh] 服务未在运行'
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
foreach ($p in $pids) {
|
|
52
|
+
Write-Output "[dsh] 停止进程 $p"
|
|
53
|
+
& taskkill /PID $p /T /F 2>$null | Out-Null
|
|
54
|
+
}
|
|
55
|
+
Start-Sleep -Seconds 2
|
|
56
|
+
if (Test-Port $PORT) { Write-Output '[dsh] 停止失败: 端口仍在监听' }
|
|
57
|
+
else { Write-Output '[dsh] 已停止' }
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function Show-Status {
|
|
61
|
+
if (Test-Port $PORT) { Write-Output "[dsh] 运行中: $URL" }
|
|
62
|
+
else { Write-Output '[dsh] 未运行' }
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# ---------- 非交互模式 ----------
|
|
66
|
+
if ($Cmd) {
|
|
67
|
+
switch ($Cmd.ToLower()) {
|
|
68
|
+
'start' { Start-Dsh }
|
|
69
|
+
'stop' { Stop-Dsh }
|
|
70
|
+
'status' { Show-Status }
|
|
71
|
+
default { Write-Output '用法: dsh-menu.ps1 -Cmd start|stop|status' }
|
|
72
|
+
}
|
|
73
|
+
exit
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
# ---------- 交互菜单 ----------
|
|
77
|
+
while ($true) {
|
|
78
|
+
Write-Output ''
|
|
79
|
+
Write-Output '======== dsh 启动器 ========'
|
|
80
|
+
Show-Status
|
|
81
|
+
Write-Output '[1] 启动并打开浏览器'
|
|
82
|
+
Write-Output '[2] 停止'
|
|
83
|
+
Write-Output '[3] 状态'
|
|
84
|
+
Write-Output '[0] 退出'
|
|
85
|
+
$choice = Read-Host '请选择'
|
|
86
|
+
switch ($choice) {
|
|
87
|
+
'1' { Start-Dsh; Start-Process $URL; }
|
|
88
|
+
'2' { Stop-Dsh }
|
|
89
|
+
'3' { Show-Status }
|
|
90
|
+
'0' { exit }
|
|
91
|
+
default { Write-Output '无效选择' }
|
|
92
|
+
}
|
|
93
|
+
}
|
package/launcher/dsh-tray.bat
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
@echo off
|
|
2
|
-
chcp 65001 >nul
|
|
3
|
-
rem DSH 系统托盘 - double click to start (blue whale = running, gray = stopped)
|
|
4
|
-
rem prefer pwsh (PowerShell 7), fallback to powershell 5.1
|
|
5
|
-
where pwsh >nul 2>nul
|
|
6
|
-
if %errorlevel%==0 (
|
|
7
|
-
start "" pwsh -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File "%~dp0dsh-tray.ps1"
|
|
8
|
-
) else (
|
|
9
|
-
start "" powershell -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File "%~dp0dsh-tray.ps1"
|
|
10
|
-
)
|
|
1
|
+
@echo off
|
|
2
|
+
chcp 65001 >nul
|
|
3
|
+
rem DSH 系统托盘 - double click to start (blue whale = running, gray = stopped)
|
|
4
|
+
rem prefer pwsh (PowerShell 7), fallback to powershell 5.1
|
|
5
|
+
where pwsh >nul 2>nul
|
|
6
|
+
if %errorlevel%==0 (
|
|
7
|
+
start "" pwsh -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File "%~dp0dsh-tray.ps1"
|
|
8
|
+
) else (
|
|
9
|
+
start "" powershell -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File "%~dp0dsh-tray.ps1"
|
|
10
|
+
)
|