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.
- package/bin/dsh-tray.js +0 -1
- package/build/build-tray-icons.ps1 +98 -98
- package/docs/system-tray-guide.md +133 -133
- package/install.ps1 +228 -184
- package/launcher/dsh-actions.ps1 +50 -50
- package/launcher/dsh-control.ps1 +40 -40
- package/launcher/dsh-lib.ps1 +50 -11
- 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 +39 -36
- package/launcher/bh-menu.bat +0 -4
- package/launcher/bh-menu.ps1 +0 -56
- package/launcher/dsh-all-menu.bat +0 -4
- package/launcher/dsh-all-menu.ps1 +0 -106
package/launcher/dsh-update.ps1
CHANGED
|
@@ -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.
|
|
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
|
-
"
|
|
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
|
+
}
|
package/launcher/bh-menu.bat
DELETED
package/launcher/bh-menu.ps1
DELETED
|
@@ -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,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
|
-
}
|