dsh-windows-tray 1.0.0 → 1.0.2
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/README.md +9 -1
- package/docs/system-tray-guide.md +133 -102
- package/install.ps1 +84 -10
- package/launcher/dsh-lib.ps1 +2 -1
- package/launcher/dsh-tray.ps1 +1 -0
- package/launcher/dsh-update.ps1 +2 -2
- package/package.json +36 -36
package/README.md
CHANGED
|
@@ -52,7 +52,7 @@ dsh 默认在终端前台运行 `dsh web`——必须留着一个命令行窗口
|
|
|
52
52
|
|
|
53
53
|
## 快速开始
|
|
54
54
|
|
|
55
|
-
前置:Windows 10/11 + [PowerShell 7](https://github.com/PowerShell/PowerShell/releases)
|
|
55
|
+
前置:Windows 10/11 + [PowerShell 7](https://github.com/PowerShell/PowerShell/releases)(7.x;缺失时自动回退 Windows PowerShell 5.1)+ Node.js **≥ 18** + 已安装 dsh(任意位置)。
|
|
56
56
|
|
|
57
57
|
```powershell
|
|
58
58
|
# 1. 全局安装
|
|
@@ -93,6 +93,14 @@ dsh-tray # 重启托盘(或右键「退出托盘」后重
|
|
|
93
93
|
|
|
94
94
|
> 部署目录固定为 `~\.dsh\launcher`,重装/更新都会覆盖旧文件,不会残留;`dsh-tray info` 可查看当前版本与部署状态。
|
|
95
95
|
|
|
96
|
+
## 卸载
|
|
97
|
+
|
|
98
|
+
```powershell
|
|
99
|
+
npm rm -g dsh-windows-tray # ① 移除 npm 包本体
|
|
100
|
+
# ② 删除快捷方式: 启动文件夹 + 桌面 各一个「DSH 系统托盘.lnk」
|
|
101
|
+
# ③ 删除部署目录 ~\.dsh\launcher (如与 dsh 控制台共用, 确认无需保留再删)
|
|
102
|
+
```
|
|
103
|
+
|
|
96
104
|
## 工作原理
|
|
97
105
|
|
|
98
106
|
```
|
|
@@ -1,102 +1,133 @@
|
|
|
1
|
-
# DSH 系统托盘(Windows)—— npm 包使用手册
|
|
2
|
-
|
|
3
|
-
> 包名: **`dsh-windows-tray`** · 部署位置: `~\.dsh\launcher` · 技术栈: PowerShell 7 + WinForms,零 npm 依赖、纯旁观者、不改 dsh 源码。
|
|
4
|
-
> 安装 / 更新 / 卸载全部走 npm 标准流程;开发归档见 [tray-dev-archive.md](tray-dev-archive.md),相关踩坑见 [powershell-pitfalls.md](powershell-pitfalls.md)。
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## 一、安装与部署
|
|
9
|
-
|
|
10
|
-
前置:Windows 10/11 + [PowerShell 7](https://github.com/PowerShell/PowerShell/releases)
|
|
11
|
-
|
|
12
|
-
```powershell
|
|
13
|
-
# 1. 全局安装
|
|
14
|
-
npm i -g dsh-windows-tray
|
|
15
|
-
|
|
16
|
-
# 2. 一键部署:自动探测 dsh/pwsh/node 路径 → 安装到 ~\.dsh\launcher
|
|
17
|
-
# → 按本机路径改写配置 → 创建开机自启 + 桌面快捷方式 → 启动托盘
|
|
18
|
-
dsh-tray install
|
|
19
|
-
|
|
20
|
-
# 3. 首次使用:把任务栏 ^ 溢出区里的鲸鱼拖到任务栏(一次性,Windows 会记住)
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
|
40
|
-
|
|
|
41
|
-
|
|
|
42
|
-
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
##
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
dsh-tray
|
|
64
|
-
dsh
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
-
|
|
1
|
+
# DSH 系统托盘(Windows)—— npm 包使用手册
|
|
2
|
+
|
|
3
|
+
> 包名: **`dsh-windows-tray`** · 部署位置: `~\.dsh\launcher` · 技术栈: PowerShell 7 + WinForms,零 npm 依赖、纯旁观者、不改 dsh 源码。
|
|
4
|
+
> 安装 / 更新 / 卸载全部走 npm 标准流程;开发归档见 [tray-dev-archive.md](tray-dev-archive.md),相关踩坑见 [powershell-pitfalls.md](powershell-pitfalls.md)。
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 一、安装与部署
|
|
9
|
+
|
|
10
|
+
前置:Windows 10/11 + [PowerShell 7](https://github.com/PowerShell/PowerShell/releases)(7.x;缺失时自动回退 Windows PowerShell 5.1)+ Node.js **≥ 18** + 已安装 dsh(任意位置)。
|
|
11
|
+
|
|
12
|
+
```powershell
|
|
13
|
+
# 1. 全局安装
|
|
14
|
+
npm i -g dsh-windows-tray
|
|
15
|
+
|
|
16
|
+
# 2. 一键部署:自动探测 dsh/pwsh/node 路径 → 安装到 ~\.dsh\launcher
|
|
17
|
+
# → 按本机路径改写配置 → 创建开机自启 + 桌面快捷方式 → 启动托盘
|
|
18
|
+
dsh-tray install
|
|
19
|
+
|
|
20
|
+
# 3. 首次使用:把任务栏 ^ 溢出区里的鲸鱼拖到任务栏(一次性,Windows 会记住)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### 安装后必做:本机参数探测 → 确认 → 回填(不要信默认值)
|
|
24
|
+
|
|
25
|
+
install 只自动改写 dsh/pwsh/node **路径**;**端口、数据目录按包默认值写入且不改**。与本机实际不一致时,症状是托盘永远灰鲸(探测错端口)或托盘/控制台启动的 web 落到空数据目录。先实测,人工确认数值,再回填到 §六 列出的**全部**填充点(只改一处会被另一处覆盖):
|
|
26
|
+
|
|
27
|
+
```powershell
|
|
28
|
+
# 实际 Web 端口:看运行中的 web 进程命令行(没在跑就看本机控制台/启动脚本里的启动命令)
|
|
29
|
+
Get-CimInstance Win32_Process -Filter "Name='node.exe'" |
|
|
30
|
+
Where-Object { $_.CommandLine -like '*web*' } |
|
|
31
|
+
ForEach-Object { $_.CommandLine } # 输出里找 --port NNNN 与 --host
|
|
32
|
+
|
|
33
|
+
# 实际数据目录:找带 settings.yaml + skins/ + profiles/ 的目录(默认 ~\.dsh,自定义部署不在那)
|
|
34
|
+
Test-Path "$env:USERPROFILE\.dsh\settings.yaml" # True=默认目录;False=自定义 DSH_HOME,必须回填
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
常用命令:
|
|
38
|
+
|
|
39
|
+
| 命令 | 作用 |
|
|
40
|
+
| :--- | :--- |
|
|
41
|
+
| `dsh-tray` | 启动托盘(已有实例则提示,不重复启动) |
|
|
42
|
+
| `dsh-tray install` | 一键部署 / 重新部署(可透传 `-DshRoot` 等参数) |
|
|
43
|
+
| `dsh-tray icons` | 重新生成鲸鱼图标(内置 512px 源图,无需浏览器) |
|
|
44
|
+
| `dsh-tray info` | 查看版本 / 安装位置 / 部署状态 |
|
|
45
|
+
|
|
46
|
+
## 二、功能一览
|
|
47
|
+
|
|
48
|
+
| 交互 | 行为 |
|
|
49
|
+
| :--- | :--- |
|
|
50
|
+
| **图标** | 🐋 品牌蓝鲸鱼 = Web 运行中;灰鲸鱼 = 未运行(官方 favicon 渲染,多尺寸 16~256px) |
|
|
51
|
+
| **悬停提示** | `Web UI 运行中 · 127.0.0.1:3088` / `Web UI 未运行 · 右键可启动` |
|
|
52
|
+
| **双击** | 打开 Web UI(未运行时提示先启动) |
|
|
53
|
+
| **右键菜单** | 顶部 `Web UI 状态` / `TUI 状态` 双状态行(含 PID);`Web UI ▸`(打开 Web UI / 启动 / 停止(带确认) / 重启);`TUI ▸`(启动 / 停止);打开日志目录 / `版本信息 ▸`(版本 / 检查更新 / 更新到最新版)/ 退出托盘 |
|
|
54
|
+
| **菜单智能禁用** | Web 运行中禁用「启动 Web UI」;TUI 运行中禁用「启动 TUI」 |
|
|
55
|
+
| **状态通知** | Web/TUI 启动与停止瞬间弹系统通知;托盘就绪弹一次提示 |
|
|
56
|
+
| **开机自启** | 登录后托盘自动出现(启动文件夹快捷方式,安装时自动创建) |
|
|
57
|
+
|
|
58
|
+
托盘每 2 秒探测一次 `127.0.0.1:3088`(TCP 连接,500ms 超时,开销可忽略);菜单动作在独立隐藏进程执行,托盘 UI 永不卡顿。
|
|
59
|
+
|
|
60
|
+
## 三、日常使用
|
|
61
|
+
|
|
62
|
+
1. **自动跟随**:在 dsh 控制台(`~\.dsh\launcher\dsh-control.ps1`)执行 启动/重启 Web 时,托盘会自动拉起(幂等)。
|
|
63
|
+
2. **手动唤起**:双击桌面「DSH 系统托盘」快捷方式;或 `dsh-tray`。
|
|
64
|
+
3. **退出托盘**:右键 → 退出托盘(只退出托盘本身,不影响 dsh;下次登录/双击快捷方式可重新唤起)。
|
|
65
|
+
4. **取消自启**:删除启动文件夹里的「DSH 系统托盘.lnk」。
|
|
66
|
+
|
|
67
|
+
## 四、更新
|
|
68
|
+
|
|
69
|
+
两种方式任选:
|
|
70
|
+
|
|
71
|
+
**方式一:托盘一键更新(推荐)**——托盘菜单「版本信息 ▸」→「检查更新」对比 npm 最新版,发现新版后点「更新到最新版」:自动 `npm install -g` → 重新部署(含本机路径改写)→ 自动重启托盘,失败不影响当前托盘。
|
|
72
|
+
|
|
73
|
+
**方式二:npm 标准流程**:
|
|
74
|
+
|
|
75
|
+
```powershell
|
|
76
|
+
npm up -g dsh-windows-tray # 拉取最新版
|
|
77
|
+
dsh-tray install # 重新部署(自动改写本机路径 + 刷新快捷方式)
|
|
78
|
+
dsh-tray # 重启托盘
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
> 部署目录固定为 `~\.dsh\launcher`,重装/更新会覆盖旧文件,不会残留;`dsh-tray info` 可查看当前版本与部署状态。
|
|
82
|
+
> ⚠️ 更新 = 重新 install,**本机手工适配(端口/数据目录等,见 §六)会被一并覆盖**——更新后按对照表重做并重启托盘,别只看安装输出就收工。
|
|
83
|
+
|
|
84
|
+
## 五、卸载
|
|
85
|
+
|
|
86
|
+
```powershell
|
|
87
|
+
npm rm -g dsh-windows-tray # 移除 npm 包本体
|
|
88
|
+
# 删除两个「DSH 系统托盘.lnk」(启动文件夹 + 桌面)
|
|
89
|
+
# 删除 ~\.dsh\launcher 目录(托盘部署文件;如与 dsh 控制台共用,确认无需保留再删)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## 六、配置
|
|
93
|
+
|
|
94
|
+
> **先探测实际值再回填,不要照抄默认列**(探测命令见 §一"安装后必做")。同一参数可能有多个填充点,缺改一处就被另一处覆盖。
|
|
95
|
+
|
|
96
|
+
| 项 | 位置 | 包默认 | 说明 |
|
|
97
|
+
| :--- | :--- | :--- | :--- |
|
|
98
|
+
| 监控端口 | ① `~\.dsh\launcher\dsh-lib.ps1` 顶部 `$PORT`;② `dsh-tray.ps1` 顶部 `param([int]$Port = …)` | `3088` | **两处必须一致**:托盘启动时先点源 lib 再执行 `$PORT = $Port`,**param 默认值会把 lib 改好的端口覆盖回去**(dsh-tray.ps1 第 27 行)——只改 lib 不改 param,托盘仍按默认端口探测 |
|
|
99
|
+
| dsh 路径 | `dsh-lib.ps1` 顶部 `$DSH_CMD / $NODE / $BIN` | 自动探测 | install 已改写,一般不用动 |
|
|
100
|
+
| 数据目录 | `dsh-lib.ps1` `$WORKDIR` + `$env:DSH_HOME` | **不设置** | 不设 DSH_HOME 时 web 默认落 `~\.dsh`——自定义数据目录的机器(如 `D:\dsh`)必须在 lib 里补 `$env:DSH_HOME`,否则托盘/控制台启动的 web 指向空目录 |
|
|
101
|
+
| 日志目录 | `dsh-lib.ps1` `$LOG_DIR`(`~\.dsh\logs`) | — | **目录须存在**:不存在时托盘 `Add-Content -ErrorAction SilentlyContinue` 静默吞日志,零日志不是没在记 |
|
|
102
|
+
| 图标颜色 | 包内 `build/build-tray-icons.ps1`(运行蓝/停止灰) | `#4176E6` / `#81858C` | — |
|
|
103
|
+
|
|
104
|
+
> ⚠️ `~\.dsh\launcher` 是部署产物,`dsh-tray install`/更新每次整体覆盖——上表手工适配重装后须重新应用(对照下表逐项核对,别凭记忆)。
|
|
105
|
+
|
|
106
|
+
### 6.1 本机落地对照(跨机器对照用,照此逐项核对)
|
|
107
|
+
|
|
108
|
+
| 项 | 包默认 | 笔记本实际(2026-08-27 实测) | 填充点 |
|
|
109
|
+
| :--- | :--- | :--- | :--- |
|
|
110
|
+
| Web 端口 | 3088 | **3080** | dsh-lib.ps1 `$PORT` + dsh-tray.ps1 param 默认值(两处) |
|
|
111
|
+
| 数据目录 | 不设→`~\.dsh` | **D:\dsh** | dsh-lib.ps1 `$WORKDIR='D:\dsh'` + `$env:DSH_HOME='D:\dsh'` |
|
|
112
|
+
| 日志目录 | `~\.dsh\logs`(可能不存在) | 已手动创建 | — |
|
|
113
|
+
| 旧控制台 | — | `D:\dsh\launcher\dsh-control.ps1` 与托盘部署并存,端口同为 3080 | 无需合并 |
|
|
114
|
+
| 装完验证 | — | `tail ~/.dsh/logs/dsh-tray.log` 应有「托盘启动 (…端口 3080)」;重启 web 应看到「状态: 未运行 → 运行中」翻转 | — |
|
|
115
|
+
|
|
116
|
+
## 七、故障排查
|
|
117
|
+
|
|
118
|
+
| 现象 | 处理 |
|
|
119
|
+
| :--- | :--- |
|
|
120
|
+
| web 明明在跑,托盘灰鲸/悬停显示"未运行" | 端口填充点不一致(十有八九是 `dsh-tray.ps1` 的 param 默认值把 lib 改好的端口覆盖回去了)——`tail ~\.dsh\logs\dsh-tray.log` 看「托盘启动」行的实际端口,对照 §六/§6.1 把两处改齐后重启托盘 |
|
|
121
|
+
| 托盘零日志 | `~\.dsh\logs` 目录不存在,托盘写日志被静默吞掉——建目录后重启托盘;重启 web 应立即出现状态翻转记录 |
|
|
122
|
+
| 任务栏看不到鲸鱼 | 点开 `^` 溢出区查找;若在,拖到任务栏(一次性)。 |
|
|
123
|
+
| 托盘图标消失 / 进程死了 | `dsh-tray` 或双击桌面快捷方式重新唤起;托盘退出不影响 dsh。 |
|
|
124
|
+
| 动作没反应 | 看 `~\.dsh\logs\dsh-tray-actions.log`(菜单动作)与 `dsh-tray.log`(状态变化)。 |
|
|
125
|
+
| 重复实例 | 命名互斥锁单实例保护(被强杀遗留的锁自动接管),正常不会重复。 |
|
|
126
|
+
| 检查更新失败 | 网络或 npm 不可用;托盘继续正常工作,稍后再试。 |
|
|
127
|
+
| dsh 内核升级了,托盘要动吗 | 不用——托盘只探测 3088 端口与 TUI 进程命令行,与内核版本解耦。 |
|
|
128
|
+
|
|
129
|
+
## 八、已知边界
|
|
130
|
+
|
|
131
|
+
- 通知弹窗受 Windows「通知设置/专注助手」控制,被系统屏蔽时图标与菜单不受影响。
|
|
132
|
+
- 托盘进程是 `pwsh`,`taskkill /T` 杀进程树会连托盘一起结束(下次登录/快捷方式/控制台操作时恢复)。
|
|
133
|
+
- 端口探测只区分 运行/停止:3088 被其他程序占用时会误判"运行中"。
|
package/install.ps1
CHANGED
|
@@ -1,19 +1,52 @@
|
|
|
1
1
|
# install.ps1 —— DSH 系统托盘 一键部署(便携包内运行)
|
|
2
|
-
# 用法: pwsh -NoProfile -ExecutionPolicy Bypass -File .\install.ps1 [-DshRoot <目录>] [-PwshPath <路径>] [-NodePath <路径>] [-NoTrayStart] [-NoShortcuts]
|
|
3
|
-
# 流程: 探测本机路径 -> 安装到 ~\.dsh\launcher ->
|
|
2
|
+
# 用法: pwsh -NoProfile -ExecutionPolicy Bypass -File .\install.ps1 [-DshRoot <目录>] [-PwshPath <路径>] [-NodePath <路径>] [-Port <端口>] [-DshHome <数据目录>] [-Auto] [-NoTrayStart] [-NoShortcuts]
|
|
3
|
+
# 流程: 探测本机路径 -> 探测端口/数据目录并确认 -> 安装到 ~\.dsh\launcher -> 回填全部读取点(含端口两处+DSH_HOME) -> 创建快捷方式 -> 启动托盘
|
|
4
|
+
# v1.0.2: 端口/数据目录实测探测 + 展示确认 + 回填全部读取点 + 自动创建日志目录 (修: param 默认值覆盖 lib 端口 / DSH_HOME 不设 / 日志目录缺失静默丢日志)
|
|
4
5
|
param(
|
|
5
6
|
[string]$DshRoot, # dsh 安装根目录 (含 dsh.cmd); 缺省自动探测
|
|
6
7
|
[string]$PwshPath, # pwsh.exe 路径; 缺省自动探测
|
|
7
8
|
[string]$NodePath, # node.exe 路径; 缺省自动探测
|
|
9
|
+
[int]$Port = 0, # Web 端口; 0=从运行中的 web 进程命令行探测
|
|
10
|
+
[string]$DshHome, # 数据目录 (含 settings.yaml); 空=自动探测
|
|
11
|
+
[switch]$Auto, # 非交互: 直接采用探测值不确认 (自更新等隐藏窗口场景)
|
|
8
12
|
[switch]$NoTrayStart, # 部署后不自动启动托盘
|
|
9
13
|
[switch]$NoShortcuts # 不创建快捷方式
|
|
10
14
|
)
|
|
11
15
|
$ErrorActionPreference = 'Stop'
|
|
12
16
|
$pkgRoot = $PSScriptRoot
|
|
13
17
|
$dst = Join-Path $env:USERPROFILE '.dsh\launcher'
|
|
18
|
+
$logDir = Join-Path $env:USERPROFILE '.dsh\logs'
|
|
14
19
|
|
|
15
20
|
Write-Host '== DSH 系统托盘 一键部署 ==' -ForegroundColor Cyan
|
|
16
21
|
|
|
22
|
+
# ---- 探测: 实际 Web 端口 (从运行中的 web 进程命令行提取, 不写死默认值) ----
|
|
23
|
+
function Find-WebPort {
|
|
24
|
+
$procs = @(Get-CimInstance Win32_Process -Filter "Name='node.exe'" -ErrorAction SilentlyContinue |
|
|
25
|
+
Where-Object { $_.CommandLine -match 'web' -and $_.CommandLine -match '--port' })
|
|
26
|
+
foreach ($p in $procs) {
|
|
27
|
+
if ($p.CommandLine -match '--port\s+(\d+)') { return [int]$Matches[1] }
|
|
28
|
+
}
|
|
29
|
+
return $null
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# ---- 探测: 实际数据目录 (特征 = settings.yaml; 环境变量优先, 其次默认 ~\.dsh) ----
|
|
33
|
+
function Find-DshHome {
|
|
34
|
+
if ($env:DSH_HOME -and (Test-Path (Join-Path $env:DSH_HOME 'settings.yaml'))) { return $env:DSH_HOME }
|
|
35
|
+
$def = Join-Path $env:USERPROFILE '.dsh'
|
|
36
|
+
if (Test-Path (Join-Path $def 'settings.yaml')) { return $def }
|
|
37
|
+
return $null
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
# ---- 交互确认 (Auto 或 stdin 不可用时直接采用探测值) ----
|
|
41
|
+
function Confirm-Value([string]$label, [string]$current) {
|
|
42
|
+
if ($Auto) { return $current }
|
|
43
|
+
try {
|
|
44
|
+
$answer = Read-Host "$label [$current]"
|
|
45
|
+
if (-not [string]::IsNullOrWhiteSpace($answer)) { return $answer.Trim() }
|
|
46
|
+
} catch { } # 非交互环境: Read-Host 失败 -> 采用探测值
|
|
47
|
+
return $current
|
|
48
|
+
}
|
|
49
|
+
|
|
17
50
|
# 1) 探测 dsh 安装根目录
|
|
18
51
|
if (-not $DshRoot) {
|
|
19
52
|
$candidates = @(
|
|
@@ -30,7 +63,7 @@ if (-not $DshRoot) {
|
|
|
30
63
|
}
|
|
31
64
|
$dsdCmd = Join-Path $DshRoot 'dsh.cmd'
|
|
32
65
|
if (-not (Test-Path $dsdCmd)) { throw "未找到 dsh 安装目录 (缺少 dsh.cmd: $dsdCmd)。请用 -DshRoot 指定。" }
|
|
33
|
-
Write-Host "[1/
|
|
66
|
+
Write-Host "[1/7] dsh 根目录: $DshRoot" -ForegroundColor Green
|
|
34
67
|
|
|
35
68
|
# 2) 探测 pwsh (PowerShell 7)
|
|
36
69
|
if (-not $PwshPath) {
|
|
@@ -40,7 +73,10 @@ if (-not $PwshPath) {
|
|
|
40
73
|
elseif (Test-Path 'D:\Program Files (x86)\PowerShell-7.6.4\pwsh.exe') { $PwshPath = 'D:\Program Files (x86)\PowerShell-7.6.4\pwsh.exe' }
|
|
41
74
|
}
|
|
42
75
|
if (-not $PwshPath -or -not (Test-Path $PwshPath)) { throw "未找到 pwsh (PowerShell 7)。请用 -PwshPath 指定。" }
|
|
43
|
-
|
|
76
|
+
# 版本校验: 托盘常驻进程依赖 PowerShell 7.x (5.1 只能降级运行)
|
|
77
|
+
$pwshVer = & $PwshPath -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' 2>$null
|
|
78
|
+
if ($pwshVer -notmatch '^7\.') { throw "pwsh 必须是 PowerShell 7.x (检测到: $pwshVer)。请安装 PowerShell 7 或用 -PwshPath 指定。" }
|
|
79
|
+
Write-Host "[2/7] pwsh: $PwshPath (v$pwshVer)" -ForegroundColor Green
|
|
44
80
|
|
|
45
81
|
# 3) 探测 node
|
|
46
82
|
if (-not $NodePath) {
|
|
@@ -49,15 +85,35 @@ if (-not $NodePath) {
|
|
|
49
85
|
elseif (Test-Path 'C:\Program Files\nodejs\node.exe') { $NodePath = 'C:\Program Files\nodejs\node.exe' }
|
|
50
86
|
}
|
|
51
87
|
if (-not $NodePath -or -not (Test-Path $NodePath)) { throw "未找到 node.exe。请用 -NodePath 指定。" }
|
|
52
|
-
|
|
88
|
+
# 版本校验: 需要 ≥ 18 (dsh 本体运行要求)
|
|
89
|
+
$nodeVer = & $NodePath -v 2>$null
|
|
90
|
+
if ($nodeVer -notmatch '^v(\d+)\.') { throw "无法识别 node 版本 (检测到: $nodeVer)。请用 -NodePath 指定有效 node.exe。" }
|
|
91
|
+
if ([int]$Matches[1] -lt 18) { throw "node 必须 ≥ 18 (检测到: $nodeVer)。请升级 Node.js 或用 -NodePath 指定。" }
|
|
92
|
+
Write-Host "[3/7] node: $NodePath (v$($Matches[1]))" -ForegroundColor Green
|
|
53
93
|
|
|
54
|
-
# 4)
|
|
94
|
+
# 4) 探测 Web 端口 + 数据目录, 展示确认
|
|
95
|
+
if ($Port -eq 0) {
|
|
96
|
+
$probed = Find-WebPort
|
|
97
|
+
if ($probed) { $Port = $probed }
|
|
98
|
+
}
|
|
99
|
+
if (-not $DshHome) {
|
|
100
|
+
$probed = Find-DshHome
|
|
101
|
+
if ($probed) { $DshHome = $probed }
|
|
102
|
+
}
|
|
103
|
+
if ($Port -eq 0) { $Port = 3088; Write-Host '警告: 未检测到运行中的 web 进程, 端口取包默认 3088 (如不符请用 -Port 指定)' -ForegroundColor Yellow }
|
|
104
|
+
if (-not $DshHome) { $DshHome = Join-Path $env:USERPROFILE '.dsh'; Write-Host "警告: 未探测到数据目录 (无 settings.yaml), 取默认 $DshHome (如不符请用 -DshHome 指定)" -ForegroundColor Yellow }
|
|
105
|
+
$Port = [int](Confirm-Value 'Web 端口' "$Port")
|
|
106
|
+
$DshHome = Confirm-Value '数据目录' $DshHome
|
|
107
|
+
Write-Host "[4/7] Web 端口: $Port ; 数据目录: $DshHome" -ForegroundColor Green
|
|
108
|
+
|
|
109
|
+
# 5) 安装到 ~\.dsh\launcher
|
|
55
110
|
New-Item -ItemType Directory -Force -Path $dst | Out-Null
|
|
56
111
|
Copy-Item -Path (Join-Path $pkgRoot 'launcher\*') -Destination $dst -Recurse -Force
|
|
57
|
-
Write-Host
|
|
112
|
+
Write-Host ('[5/7] 已安装到 ' + $dst) -ForegroundColor Green
|
|
58
113
|
|
|
59
|
-
#
|
|
114
|
+
# 6) 回填全部读取点 + 自动创建日志目录
|
|
60
115
|
$lib = Join-Path $dst 'dsh-lib.ps1'
|
|
116
|
+
$tray = Join-Path $dst 'dsh-tray.ps1'
|
|
61
117
|
$bin = Join-Path $DshRoot 'node_modules\@deepseek-ai\dsh\lib\bin.js'
|
|
62
118
|
if (-not (Test-Path $bin)) { Write-Host "警告: 未找到 $bin (dsh 包结构可能不同), 请检查 dsh-lib.ps1 的 \$BIN" -ForegroundColor Yellow }
|
|
63
119
|
$map = [ordered]@{
|
|
@@ -65,6 +121,7 @@ $map = [ordered]@{
|
|
|
65
121
|
'$NODE = ' = "`$NODE = '$($NodePath -replace "'", "''")'"
|
|
66
122
|
'$BIN = ' = "`$BIN = '$($bin -replace "'", "''")'"
|
|
67
123
|
'$WORKDIR = ' = "`$WORKDIR = '$($DshRoot -replace "'", "''")'"
|
|
124
|
+
'$PORT = ' = "`$PORT = $Port"
|
|
68
125
|
'$PWSH = ' = "`$PWSH = '$($PwshPath -replace "'", "''")'"
|
|
69
126
|
}
|
|
70
127
|
$lines = Get-Content $lib
|
|
@@ -73,8 +130,24 @@ for ($i = 0; $i -lt $lines.Count; $i++) {
|
|
|
73
130
|
if ($lines[$i].StartsWith($k)) { $lines[$i] = $map[$k]; break }
|
|
74
131
|
}
|
|
75
132
|
}
|
|
133
|
+
# DSH_HOME: 先清旧行, 非默认数据目录时写入 (默认 ~\.dsh 不设 = dsh 原生行为)
|
|
134
|
+
$lines = @($lines | Where-Object { $_ -notmatch '^\$env:DSH_HOME\s*=' })
|
|
135
|
+
$defaultHome = Join-Path $env:USERPROFILE '.dsh'
|
|
136
|
+
if ($DshHome -ne $defaultHome) {
|
|
137
|
+
$lines = @($lines | ForEach-Object {
|
|
138
|
+
if ($_ -match '^\$WORKDIR') { $_; "`$env:DSH_HOME = '$($DshHome -replace "'", "''")' # 数据目录 (install 回填)" }
|
|
139
|
+
else { $_ }
|
|
140
|
+
})
|
|
141
|
+
}
|
|
76
142
|
Set-Content -Path $lib -Value $lines -Encoding utf8
|
|
77
|
-
|
|
143
|
+
# dsh-tray.ps1 param 默认值 (点源 lib 后 $PORT = $Port 会把 lib 改好的端口覆盖回去, 必须两处一致)
|
|
144
|
+
# 注意: param 块是多行格式 (param( 换行 [int]$Port = …), 只匹配参数行本身
|
|
145
|
+
$trayText = Get-Content $tray -Raw
|
|
146
|
+
$trayText = $trayText -replace '\[int\]\$Port = \d+', "[int]`$Port = $Port"
|
|
147
|
+
Set-Content -Path $tray -Value $trayText -Encoding utf8
|
|
148
|
+
# 自动创建日志目录 (缺失时 Add-Content -ErrorAction SilentlyContinue 会静默丢日志, 零排查线索)
|
|
149
|
+
New-Item -ItemType Directory -Force -Path $logDir | Out-Null
|
|
150
|
+
Write-Host "[6/7] 已回填 (端口 $Port ×2处 + DSH_HOME) + 日志目录就绪" -ForegroundColor Green
|
|
78
151
|
|
|
79
152
|
# 快捷方式: 开机自启 + 桌面
|
|
80
153
|
if (-not $NoShortcuts) {
|
|
@@ -105,6 +178,7 @@ if (-not $NoTrayStart) {
|
|
|
105
178
|
|
|
106
179
|
Write-Host ''
|
|
107
180
|
Write-Host '部署完成! 常用命令:' -ForegroundColor Cyan
|
|
108
|
-
Write-Host
|
|
181
|
+
Write-Host " 手动唤起托盘: 桌面「DSH 系统托盘」/ 控制台选项 5"
|
|
109
182
|
Write-Host ' 取消自启: 删除启动文件夹里的「DSH 系统托盘.lnk」'
|
|
110
183
|
Write-Host ' 卸载: 删除快捷方式 + 删除 ~\.dsh\launcher'
|
|
184
|
+
Write-Host " 验证: $logDir\dsh-tray.log 首行「托盘启动 (…端口 $Port)」" -ForegroundColor Cyan
|
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.2' # 托盘版本 (与 npm 包版本同步, 用于日志/排查)
|
|
16
16
|
$TRAY_PKG = 'dsh-windows-tray' # npm 包名 (托盘自更新)
|
|
17
17
|
$TRAY_SCRIPT = Join-Path $PSScriptRoot 'dsh-tray.ps1'
|
|
18
18
|
|
|
@@ -163,3 +163,4 @@ function Ensure-DshTray {
|
|
|
163
163
|
}
|
|
164
164
|
return $false
|
|
165
165
|
}
|
|
166
|
+
|
package/launcher/dsh-tray.ps1
CHANGED
package/launcher/dsh-update.ps1
CHANGED
|
@@ -90,8 +90,8 @@ if (-not (Test-Path $newInstall)) {
|
|
|
90
90
|
exit 1
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
# 3) 运行新包 install.ps1 (重新部署 +
|
|
94
|
-
$code = Run-HiddenCmd ('/c ""' + $PWSH + '" -NoProfile -ExecutionPolicy Bypass -File "' + $newInstall + '" -NoTrayStart 2>nul "', 120000)
|
|
93
|
+
# 3) 运行新包 install.ps1 (重新部署 + 探测回填 + 快捷方式, 不启动托盘; -Auto=隐藏窗口非交互)
|
|
94
|
+
$code = Run-HiddenCmd ('/c ""' + $PWSH + '" -NoProfile -ExecutionPolicy Bypass -File "' + $newInstall + '" -Auto -NoTrayStart 2>nul "', 120000)
|
|
95
95
|
if ($code -ne 0) {
|
|
96
96
|
Log "自更新失败: install.ps1 退出码 $code"
|
|
97
97
|
Show-Balloon '自更新失败:部署出错,详见日志' 'Error'
|
package/package.json
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
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
|
-
"private": false
|
|
36
|
-
}
|
|
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
|
+
}
|