🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

一键重启按钮 FIZMIE/dsh-restart-button

DeepSeek 客户端v0.1.2
FIZMIE31 天前有提交已提供中文文档扫描:含敏感能力兼容 / 相关生态

在侧栏加刷新按钮,一键重启桌面应用

30.8/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/1 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

相关生态插件(非 dsh 原生,按其对应运行时安装)
git clone https://github.com/FIZMIE/dsh-restart-button.git

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么
生态插件
可安装,未声明 dsh 能力
装得上吗
静态安装检查有提示项,装前建议看一眼 README
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 31 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意

npm 同名包「dsh-restart-button」归属 jiqiu0709/dsh-restart-button,装到的可能不是本插件

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包dsh-restart-button @ 0.1.2
✓Node 引擎要求 >=22.6 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/15 04:22:11

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 15 处,展示前 15 条)
  • 读取本地文件
    lib/index.js:85
    const existing = readFileSync(tokenFile(), 'utf8').trim();
  • 写入本地文件
    lib/index.js:92
    mkdirSync(stateDir(), { recursive: true });
  • 写入本地文件
    lib/index.js:93
    writeFileSync(tokenFile(), `${token}\n`, 'utf8');
  • 读取本地文件
    lib/index.js:110
    if (existsSync(join(dir, 'resources', 'app.asar')) || existsSync(join(dir, 'resources', 'app'))) return dir;
  • 读取本地文件
    lib/index.js:138
    const installed = readdirSync(root)
  • 读取本地文件
    lib/index.js:142
    .sort((a, b) => statSync(b).size - statSync(a).size);
  • 读取本地文件
    lib/index.js:148
    return candidates.find((candidate) => existsSync(candidate));
  • 读取本地文件
    lib/index.js:176
    const found = candidates.find((candidate) => existsSync(candidate));
  • 写入本地文件
    lib/index.js:547
    mkdirSync(stateDir(), { recursive: true });
  • 写入本地文件
    lib/index.js:548
    writeFileSync(helperFile(), HELPER_SOURCE, 'utf8');
  • 写入本地文件
    lib/index.js:549
    writeFileSync(activateFile(), ACTIVATE_SOURCE, 'utf8');
  • 写入本地文件
    lib/index.js:550
    writeFileSync(launcherFile(), LAUNCHER_SOURCE, 'utf8');
  • 执行外部命令来自配置/变量
    lib/index.js:564
    const child = spawn(
  • 发起网络请求
    client/client.js:81
    const response = await fetch(BASE + "/health", { cache: "no-store" });
  • 发起网络请求
    client/client.js:105
    const response = await fetch(BASE + "/restart", {
扫描于 2026/11/1(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/cordis
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 侧栏添加刷新按钮
  • 一键重启桌面应用
  • 智能体调用重启路由

DeepSeek Harness 桌面版一键重启:侧边栏按钮加一条智能体可调用的重启路由。

README

由 DeepSeek 最新模型翻译生成
dsh-restart-button 给 DeepSeek Harness 桌面版加一个一键重启——侧栏品牌行「DeepSeek Harness」字样右侧一个刷新按钮,外加一条 HTTP 接口,让 Agent(或脚本)可以自己重启应用。 侧栏品牌行里的重启按钮 重启按钮,就在「DeepSeek Harness」字样右侧。 ⚠️ 必须先加一条 profile 补丁,按钮才会出现 侧栏品牌行是 single 槽,而 dsh-client-ui-slots 对 single 槽的第二次注册会直接抛错——所以必须让随附的 @deepseek-ai/dsh-client-ui-brand-official 先让位。 不加这条:插件能装、HTTP 接口也能用,但按钮不会出现。 把 install/profile-patch.yml 追加到 $DSH_HOME/profiles//cordis.patch.yml——详见安装。 为什么需要它 打包发布的 DeepSeek Harness 桌面版没有任何重启入口: | 你以为会有入口的地方 | 实际情况 | | 托盘右键菜单 | 只有「打开应用」和「退出应用」 | | 应用菜单 | 代码里确实有 Restart App and Host,但它被 const development = !
展开完整文档(README 剩余 1 节)
dsh-restart-button

给 DeepSeek Harness 桌面版加一个一键重启——侧栏品牌行「DeepSeek Harness」字样右侧一个刷新按钮,外加一条 HTTP 接口,让 Agent(或脚本)可以自己重启应用。

侧栏品牌行里的重启按钮

重启按钮,就在「DeepSeek Harness」字样右侧。

⚠️ 必须先加一条 profile 补丁,按钮才会出现

侧栏品牌行是 single 槽,而 dsh-client-ui-slots 对 single 槽的第二次注册会直接抛错——所以必须让随附的 @deepseek-ai/dsh-client-ui-brand-official 先让位。

不加这条:插件能装、HTTP 接口也能用,但按钮不会出现。

把 install/profile-patch.yml 追加到 $DSH_HOME/profiles//cordis.patch.yml——详见安装。

为什么需要它

打包发布的 DeepSeek Harness 桌面版没有任何重启入口:

| 你以为会有入口的地方 | 实际情况 |
| 托盘右键菜单 | 只有「打开应用」和「退出应用」 |
| 应用菜单 | 代码里确实有 Restart App and Host,但它被 const development = !app.isPackaged 挡着,只在开发模式出现 |
| 关闭窗口 | 缩到托盘,不会退出 |

于是每次装插件或改配置需要新进程时,都得托盘退出 → 找图标 → 再启动。这个插件补上那个按钮。

环境要求

| 系统 | Windows(树外 worker 依赖 WMI、wscript.exe 和 Win32 取前台) |
| 宿主 | DeepSeek Harness 0.2.0-rc.2 桌面版 |
| profile 补丁 | 必需——一条 disabled: true,见下面的第 1 步。不加这条,插件能装但按钮不会出现。 |

安装

1. 先加 profile 补丁(必需)

侧栏的 7 个渲染位几乎都是 single 槽,而 slot 注册表对 single 槽的第二次注册会直接抛错(dsh-client-ui-slots:single slot "" already has a registration)。品牌行归随附的 @deepseek-ai/dsh-client-ui-brand-official 所有,所以它必须让位。侧栏自己的文档把这件事写成受支持的用法—— "部署可以替换品牌标记或名称"——而本插件会重新渲染官方 wordmark,标题看起来不变。

在 $DSH_HOME/profiles//cordis.patch.yml 末尾追加:

- id: ui-brand-official
name: "@deepseek-ai/dsh-client-ui-brand-official"
disabled: true

(ui-brand-official 是 @deepseek-ai/dsh-web-app/cordis.patch.yml 里声明的行 id。)

2. 安装 bundle

DSH 插件就是一个普通的 profile bundle,两种方式都行:

从本仓库安装
dsh plugin --profile desktop add git+https://github.com/FIZMIE/dsh-restart-button.git

或从本地目录安装
dsh plugin --profile desktop add C:\path\to\dsh-restart-button

3. 刷新页面

浏览器半区的变化由 dsh-client-modules 增量扫描,不需要重启进程——刷新一下即可。
按钮会出现在「DeepSeek Harness」字样右侧。

你会得到

- 品牌行按钮——「DeepSeek Harness」字样右侧的刷新图标。点击 → 确认 → 整个应用重启:窗口消失、自己回来、被切到前台、页面自动刷新。
- 给 Agent / 脚本的通道——POST /dsh-restart-button/restart,Agent 可以自己重启,不用你动手。

HTTP 接口

全部挂在宿主 web server 的 /dsh-restart-button 下:

| 方法 | 路径 | 用途 |
| GET | /status | 进程身份、解析出的可执行文件、是否可重启 |
| GET | /health | bootId + 运行时长;浏览器半区靠它发现新进程 |
| POST | /restart | 安排重启,在应用消失前先返回 202 |

POST /restart 只接受环回来源,且要求请求要么带应用自身的 origin,要么带本机令牌(写在 $DSH_HOME/.dsh-restart-button/token)。令牌就是给 Agent 用的通道:

$token = (Get-Content "$env:DSH_HOME\.dsh-restart-button\token" -Raw).Trim()
Invoke-RestMethod -Method Post -Uri "http://127.0.0.1:19387/dsh-restart-button/restart"
-Headers @{ 'X-DSH-Restart-Token' = $token }

实现要点

重启这个特定的应用出乎意料地麻烦,代码里到处写着原因。简版如下。

进程模型

桌面外壳(lib/main.js)是 Electron 主进程。它把 DSH 宿主——也就是所有插件——作为子进程拉起,并带上 ELECTRON_RUN_AS_NODE=1 与一个 IPC 通道。所以插件里:

- 拿不到 app 对象,不能调用 app.relaunch();
- 子 → 父的 IPC 只传 ready 事件,没有"请重启"这种消息。

重启只能由另一个进程来完成。

树外的 worker

最早的方案是让一个助手杀掉应用再拉起它。它一直工作良好——直到应用死掉的那一刻:助手跟着一起死了, restart.log 停在 kill 那一行之后。原因是助手仍是应用的后代进程,应用被终结时它的进程树(job object)被一并清掉。

解法是根本别待在那棵树里。助手的第一件事,是通过 WMI 提供程序造一个自己的副本:

Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{ CommandLine = '...' }

这样创建的进程,父进程是 WmiPrvSE.exe(服务进程),并且运行在交互会话里(所以从它启动的 GUI 应用可见)。
这个 worker 之后负责等待旧应用消失、重新拉起、把窗口切到前台。启动链用 wscript.exe + .vbs 保证全程无窗口,并且等待 worker 结束(Run cmd, 0, True)——因为实测发现,非 detach 的子进程在父进程立刻退出时会被杀掉。

四个值得记住的 Windows 坑

| 坑 | 后果 | 本插件的做法 |
| 宿主子进程带 ELECTRON_RUN_AS_NODE=1 | 原样传给 DeepSeek Harness.exe,它会以纯 Node 模式启动:弹出控制台窗口、GUI 永不出现,看起来就是"杀掉了但没拉起" | 复制环境变量并删除它 |
| windowsHide 实际是 STARTF_USESHOWWINDOW + wShowWindow = SW_HIDE | GUI 应用的首个 ShowWindow 会服从它,窗口被创建却保持隐藏,必须点任务栏才出来 | 拉起应用时绝不传 windowsHide |
| detached: true 与 detach 的 powershell.exe | 需要控制台的控制台程序在 detach 下根本不执行 | 助手(Node 进程)可以 detach;取前台那步的 PowerShell 必须非 detach |
| "进程存在"不等于"窗口可用" | 旧助手报成功时用户还在盯着空气 | 以端口恢复监听作为确认信号,并记录真实耗时 |

另外:杀进程用进程号直接 process.kill(),不再 spawn taskkill(少一个控制台进程,关键路径少约 1.1 秒);重新拉起最多 5 次;全过程写入 $DSH_HOME/.dsh-restart-button/restart.log。

一次真实重启长什么样

下面是从 $DSH_HOME/.dsh-restart-button/restart.log 里原样抄出来的一次真实重启:

15:00:53.877 [primary] wmi create -> ReturnValue=0 pid=24172
15:00:53.877 [primary] relaunch delegated to out-of-tree worker pid 24172
15:00:53.919 [worker] helper start pid=22748 port=19387 main=10192 host=20620
15:00:55.079 [primary] kill main(10192)=true host(20620)=true
15:00:55.141 [worker] port 19387 free after 800ms
15:00:55.159 [worker] relaunch attempt 1/5: spawned pid=23248
15:00:57.679 [worker] app is listening on 19387 after 2535ms (attempt 1)
15:00:57.690 [worker] activation requested for pid 23248
15:00:59.436 [activate] brought the window to the foreground

这个顺序本身就说明了整个设计:primary 在杀掉任何东西之前先造出树外 worker,下一行 worker 已经在运行;而它的 port free 出现在应用被终结之后——这恰恰是过去会失败的地方。从终止旧进程到窗口回到前台约 5.5 秒,其中 2.5 秒是 DeepSeek Harness 自身的启动时间。

要求与限制

- 仅 Windows。 树外 worker 依赖 WMI、wscript.exe 和 Win32 取前台。
- 针对 DeepSeek Harness 0.2.0-rc.2 开发。它读取 launcher 发布的 profileContext 服务,除自身文件外不改动任何东西,但确实依赖可能变动的内部实现。
- 重启是强杀(TerminateProcess),不是优雅退出:进行中的任务会被中断。
DSH 的会话数据是追加写的 JSONL,落盘数据风险低,但不是零。
- 杀进程按进程号(Electron 主进程 + DSH 宿主子进程),不影响其它进程。
- 重新拉起有上限:最多 5 次,之后放弃并写日志。
- 剩下的等待时间大部分是 DeepSeek Harness 自身的启动成本,不是本插件的——日志里会记 app is listening on after ms,可以把两者区分开。

工具

两个小工具,开发时也用它们:

从 lib/index.js 里的模板重新生成运行时产物,并断言本插件依赖的每一项不变式(10 项)。
node tools/extract-helper.mjs

从插件外部重启正在运行的应用——当 lib/index.js 本身被改动时的引导路径,因为宿主侧 JavaScript 只在新进程里生效。
node tools/launch-helper.mjs

npm run check 会用一次性目录跑前者。

许可

MIT — 见 LICENSE。
预览分享卡片长什么样 ↓FIZMIE/dsh-restart-button
分享 · DeepSeek Harness Hub
FIZMIE/dsh-restart-button

在侧栏加刷新按钮,一键重启桌面应用

回到顶部