dsh-auto-open-web: Open DSH Web GUI in a standalone application window

前言

在终端执行 dsh web 启动 Web profile 后,DSH 默认会用系统默认浏览器打开一个普通标签页承载 GUI。这个标签页和日常浏览混在一起,任务栏里也没有独立的窗口身份,切换、查找都不方便。DSH 的理念是「一切皆插件」,这个问题同样可以交给插件解决:dsh-auto-open-web 是一个常驻插件,在 HTTP 服务绑定完成、取得实际监听端口后,自动以独立应用窗口(或浏览器 --app 窗口)打开 GUI,并在设置 → 插件配置中提供配置卡片。下面介绍它的行为、配置和安装方式。

这是什么

dsh-auto-open-web 是 jinsiyu 维护的 DSH 插件,MIT 许可证。一句话定位:dsh web profile 启动后自动打开独立应用窗口(或网页标签页)的常驻插件,内置随包分发的 WebView2 宿主(DshAppWindow.exe)实现轻量级桌面化。

它是一个组合包(bundle):package.json 的 dsh.bundle 声明配置层文件 cordis.patch.yml,安装到 web profile 后按包名激活插件行(name: auto-open-web)。

与官方默认行为的关系:安装本插件后,插件的 bundle 补丁会把 web-runtime.openBrowser 置为 false,打开行为由插件接管;卸载插件后恢复官方默认行为。

工作机制

触发时机

插件把 webServer 声明为硬依赖(inject),DSH 会等 webServer 初始化完成(HTTP 服务绑定、端口写入)后才激活本插件,因此插件激活时端口已可用,无需等待轮询。端口取自 webServer 服务的真实监听值,--port 自定义端口和 --port 0 都能拿到正确结果。

WebView2 宿主(windowKind: webview2,默认,仅 Windows)

  1. 启动随包分发的 DshAppWindow.exe(WinForms + WebView2,独立进程,无标签栏/地址栏),直接加载 GUI 根地址;
  2. 任务栏/窗口图标为 DSH 图标;
  3. 随 DSH 退出:宿主监视父进程 PID,DSH 进程结束时窗口一并关闭;
  4. 记忆窗口大小/位置/最大化状态(%LOCALAPPDATA%\DeepSeekHarness\window-state.json),关闭时保存、启动时恢复。

浏览器应用窗口(windowKind: browser)

--app 参数启动 Edge/Chrome 专用实例,--user-data-dir=~/.dsh/<browser>-app-profile,进程树与存储独立,不与正常浏览器页面共用。

随 DSH 退出(含强杀):专用实例加入 Job Object(JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE,koffi 驱动),DSH 正常退出、被 taskkill /F 强杀、崩溃、关机时实例都会随之结束。另有退出清理与下次启动预清理两层兜底。

降级与抑制

  • 所选窗口类型不可用时(宿主缺失、浏览器找不到、非 Windows 等),降级为系统默认浏览器打开(官方同款 open 方式,普通标签页),保证至少能打开 GUI;
  • dsh web --no-open 或 SSH 会话时不打开任何窗口/页面:插件读取与官方同一来源的 webStartup 服务做同样的抑制。

配置

配置有两条途径,等价:

1、设置页卡片(推荐):设置 → 插件配置 → 「自动打开网页」卡片,可编辑 appWindowwindowKindbrowserPathexitOnWindowClose

2、行配置:在 cordis.patch.yml 中编辑,作为启动种子,设置卡片保存前生效。

四个配置项的默认值:

字段 默认值
appWindow true
windowKind webview2
exitOnWindowClose false
browserPath ''

browserPath 用于手动指定浏览器可执行文件路径(仅浏览器模式使用)。设置卡片提供两个辅助按钮:

  • 「浏览」:弹出原生文件对话框(子进程 + koffi 驱动 IFileOpenDialog);
  • 「测试」:真实拉起一个 --app 专用测试实例(独立 user-data-dir ~/.dsh/<browser>-test-profile,不污染正式实例),数秒后自动结束测试进程树。

exitOnWindowClose 是实验性功能,默认关闭,仅 appWindow 开启时生效:窗口进程正常退出(用户关闭窗口)时触发 process.exit(0);启动失败、崩溃、被强杀等非 0 退出码不触发,避免误退出。

browserPath 行配置示例(~/.dsh/profiles/web/cordis.patch.yml):

- id: auto-open-web
  config:
    browserPath: 'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe'

这一步是给浏览器模式指定可执行文件的写法:按插件行 id auto-open-web 覆写对应 config 字段。

WebView2 宿主的系统要求(仅 webview2 模式)

  • Windows 10 1803+ / Windows 11 / Windows Server 2016+(Win7/8.1 已于 2023-01 终止支持);
  • WebView2 Runtime(常青版,通常随 Edge 预装;README 记录本机已验证 151.x);
  • 无 .NET 10 运行时要求:宿主自 0.1.15 起目标 .NET Framework 4.7.2,由 Windows 10 1803+ / Windows 11 操作系统自带。

安装与卸载

npm 注册表安装:

dsh plugin --profile web add dsh-auto-open-web

其他安装方式(任选其一):

# tarball(README 示例,文件名以实际打包产物为准)
dsh plugin --profile web add ./dsh-auto-open-web-0.1.5.tgz

# 源码 checkout(开发期,改动即时生效;使用绝对路径)
dsh plugin --profile web add C:\path\to\dsh-auto-open-web

# GitHub 源码
dsh plugin --profile web add github:jinsiyu/dsh-auto-open-web#main

卸载(同时移除依赖与对应配置层):

dsh plugin --profile web remove dsh-auto-open-web

安装后重启 dsh web 生效,设置页会出现「自动打开网页」卡片。

安装产物的差异需要注意:

  • npm 包已包含 WebView2 宿主编译产物;
  • GitHub main 分支与源码 checkout 方式不含 host-publish/(构建产物被 .gitignore 忽略),webview2 模式需先在 node_modules/dsh-auto-open-web 下执行 pnpm run build:host 生成(需 .NET SDK);browser 模式无需构建。

自行打包时,在源码目录执行 pnpm pack,prepack 钩子会先编译 WebView2 宿主(dotnet publish),产出 tgz 文件。

实现细节

  • 零 dependencies:运行时依赖由 DSH 部署提供,以 optional peer 声明。@deepseek-ai/dsh 声明兼容范围 >=0.1.0-rc.8 <0.2.0(不做运行时版本检测);@deepseek-ai/schemastery ^3.18.1koffi 仅用于 Windows 的 Job Object、进程校验与原生对话框,运行时解析部署副本,失败仅降级。
  • 设置卡片 UI 完全自绘(自 0.1.10 起),观感经官方设计令牌变量(--dsw-alias-* / --dsw-static-*)对齐,浅/深色主题自动跟随。
  • WebView2 宿主的窗口/任务栏图标来自插件生成的 DSH .ico(~/.dsh/auto-open-web-icon.ico,自 0.1.14 起缓存固定,后续启动直接复用);宿主 exe 另通过 <ApplicationIcon> 内嵌图标兜底。

适用场景与注意事项

适合:

  • 在 Windows 本机运行 dsh web,希望 GUI 以独立窗口呈现、有独立任务栏图标、随 DSH 进程一起退出的用户;
  • 想要轻量级桌面化、不想为此安装额外运行时的用户(宿主 exe 随插件包分发,目标 .NET Framework 4.7.2 由系统自带)。

注意事项:

  • macOS/Linux:webview2 模式不可用,会降级为默认浏览器打开;browser 模式未测试;
  • browser 模式下重启 DSH 后旧窗口保持原样,需手动刷新,可能与新窗口短暂并存;webview2 模式下旧宿主窗口随旧 DSH 进程退出;
  • exitOnWindowClose 为实验性功能,默认关闭;
  • 插件不做 DSH 版本的运行时检测,安装前确认自己的 DSH 版本落在声明的兼容范围 >=0.1.0-rc.8 <0.2.0 内;
  • 插件以当前 dsh 进程的权限运行,安装前应检查插件源码与许可证(MIT)。

结语

经过上面的步骤,dsh web 启动后的打开行为就从「去浏览器里找标签页」变成「自动弹出独立应用窗口」:窗口身份、图标、退出行为都与 DSH 进程对齐,配置上既有设置页卡片也有行配置,做不到的场景(非 Windows、宿主缺失)会安静降级到默认浏览器。

  • 社区插件目录页:https://www.skillhub.cn/plugins/jinsiyu/dsh-auto-open-web
  • GitHub 仓库:https://github.com/jinsiyu/dsh-auto-open-web

需要说明的是,上述目录为独立社区站点的收录页面,与 DeepSeek / 幻方无官方从属关系。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye