Files
dsh-enhancements/tools/dsh-app.ps1
T
江晨 096e5af69b fix: 修复 dsh.ico 帧偏移 bug + 托盘图标加固 + BOM 经验
- tools/repair-ico.ps1: 检测并修复 ICO 帧偏移量未计目录长度的损坏模式
- assets/dsh.ico: 已修复(原文件偏移全错,.NET Icon 无法加载)
- tools/dsh-app.ps1: 归档加固版托盘脚本(图标加载兜底)
- tools/dsh-app.ps1.README.md: 修复记录 + UTF-8 BOM 踩坑
2026-08-17 12:53:53 +08:00

118 lines
4.6 KiB
PowerShell

# DeepSeek Harness - 托盘应用
# 双击桌面快捷方式启动:拉起 dsh web 服务(若未运行),右下角托盘常驻,
# 右键菜单可"打开主界面"(Edge 独立应用窗口)或"退出"(停止服务并退出)。
$ErrorActionPreference = 'Continue'
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$DshBin = 'C:\Users\a1703\AppData\Local\npm-cache\_npx\1e7f6d9597241db0\node_modules\@deepseek-ai\dsh\lib\bin.js'
$IconFile = 'C:\Users\a1703\.dsh\assets\dsh.ico'
$LogDir = 'C:\Users\a1703\.dsh\logs'
$LogFile = Join-Path $LogDir 'dsh-app.log'
$Url = 'http://127.0.0.1:3080'
$Port = 3080
$WorkDir = 'C:\Users\a1703'
$Edge = @('C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe', 'C:\Program Files\Microsoft\Edge\Application\msedge.exe') | Where-Object { Test-Path $_ } | Select-Object -First 1
New-Item -ItemType Directory -Path $LogDir -Force | Out-Null
function Log([string]$msg) {
try { Add-Content -Path $LogFile -Value ("{0} {1}" -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), $msg) -Encoding UTF8 } catch {}
}
function Test-Port([int]$port) {
try {
$c = New-Object System.Net.Sockets.TcpClient
$ar = $c.BeginConnect('127.0.0.1', $port, $null, $null)
if (-not $ar.AsyncWaitHandle.WaitOne(500)) { $c.Close(); return $false }
$c.EndConnect($ar); $c.Close(); return $true
} catch { return $false }
}
function Stop-Dsh {
Get-CimInstance Win32_Process -Filter "Name='node.exe'" -ErrorAction SilentlyContinue |
Where-Object { $_.CommandLine -like '*@deepseek-ai\dsh*lib*bin.js*' } |
ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
}
function Stop-EdgeApp {
Get-CimInstance Win32_Process -Filter "Name='msedge.exe'" -ErrorAction SilentlyContinue |
Where-Object { $_.CommandLine -like '*--app=http://127.0.0.1:3080*' } |
ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }
}
function Open-Main {
try {
if ($Edge) { Start-Process $Edge -ArgumentList "--app=$Url" }
else { Start-Process $Url }
Log 'opened main window'
} catch { Log "open main failed: $_" }
}
# 单实例保护:已有托盘在运行则直接弹出主界面并退出本进程
$mutex = New-Object System.Threading.Mutex($true, 'DSHWebTrayApp')
if (-not $mutex.WaitOne(0)) {
Log 'another instance is running; opening main window only'
Open-Main
exit
}
# 确保服务在跑
if (-not (Test-Port $Port)) {
Log 'dsh not listening; starting it'
try {
Start-Process -FilePath 'node' -ArgumentList @($DshBin, 'web') -WorkingDirectory $WorkDir -WindowStyle Hidden `
-RedirectStandardOutput (Join-Path $LogDir 'dsh-web.out.log') -RedirectStandardError (Join-Path $LogDir 'dsh-web.err.log')
} catch { Log "start dsh failed: $_" }
$ready = $false
for ($i = 0; $i -lt 120; $i++) {
Start-Sleep -Milliseconds 500
if (Test-Port $Port) { $ready = $true; break }
}
if ($ready) { Log 'dsh is ready' } else { Log 'dsh did not become ready within 60s' }
} else {
Log 'dsh already listening'
}
# 托盘图标与菜单
$notify = New-Object System.Windows.Forms.NotifyIcon
try {
$notify.Icon = New-Object System.Drawing.Icon($IconFile)
} catch {
Log "icon load failed: $_; falling back"
try {
# 兜底1:同目录下尝试修复版/其他 .ico
$alt = Get-ChildItem (Split-Path $IconFile) -Filter '*.ico' -ErrorAction SilentlyContinue | Select-Object -First 1
if ($alt) { $notify.Icon = New-Object System.Drawing.Icon($alt.FullName) }
} catch {}
if (-not $notify.Icon) {
try { $notify.Icon = [System.Drawing.Icon]::ExtractAssociatedIcon((Get-Process -Id $PID).Path) } catch {}
}
}
$notify.Text = 'DeepSeek Harness'
$notify.Visible = $true
$menu = New-Object System.Windows.Forms.ContextMenuStrip
$itemOpen = New-Object System.Windows.Forms.ToolStripMenuItem('打开主界面')
$itemOpen.Add_Click({ Open-Main })
$itemExit = New-Object System.Windows.Forms.ToolStripMenuItem('退出')
$itemExit.Add_Click({
Log 'exit requested'
try { $notify.Visible = $false } catch {}
Stop-EdgeApp
Stop-Dsh
try { $ctx.ExitThread() } catch {}
})
$menu.Items.Add($itemOpen) | Out-Null
$menu.Items.Add($itemExit) | Out-Null
$notify.ContextMenuStrip = $menu
$notify.Add_MouseDoubleClick({
if ($_.Button -eq [System.Windows.Forms.MouseButtons]::Left) { Open-Main }
})
$ctx = New-Object System.Windows.Forms.ApplicationContext
Log 'tray app running'
Open-Main
[System.Windows.Forms.Application]::Run($ctx)