# dsh-open-with **Repository Path**: leecmd786567/dsh-open-with ## Basic Information - **Project Name**: dsh-open-with - **Description**: DeepSeek Harness 文件打开方式插件:按扩展名独立配置本地应用,右键文档即可用指定程序打开,不受 Windows 默认关联影响。 - **Primary Language**: JavaScript - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-11-01 - **Last Updated**: 2026-11-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # dsh-open-with > **V1.0 公开发行版**。普通用户请直接看 [INSTALL.md](INSTALL.md) 或 [安装与使用说明.pdf](安装与使用说明.pdf);本文是开发者说明。 **Topics:** `dsh-plugin` · `deepseek-harness` · `dsh` · `windows` · `file-association` · `electron` 给 DeepSeek Harness(DSH)加一个**文件右键菜单**,并让插件**自己保存“哪种文件用哪个程序打开”**,不依赖、也不会被 Windows 默认关联改掉。 - 右键对话里的文档卡片、回复里的文件链接: - **用 Typora 打开**(或你为该扩展名配置的程序) - **打开方式…**:插件配置 + 系统关联应用,可临时选择并记住 - **在文件夹中显示** - **复制路径** - **在侧栏预览** - **打开方式设置…**:跳到插件设置页 - 插件设置页(**Plugins → dsh-open-with → 默认打开方式**): - 插件页只显示摘要(已配置类型 + 前几个映射 + 打开设置);**表格在宽抽屉里编辑** - 点「打开设置」或右键菜单「打开方式设置…」直接打开抽屉 - 按扩展名配置应用:`md` → `C:\Program Files\Typora\Typora.exe` - 扩展名格子和应用格子都是下拉选择;路径格可直接粘贴,右侧文件夹图标可浏览选 `.exe` - 自动保存,无需点保存;配置存在 `%USERPROFILE%\.dsh\open-with.json` > 关键点:配置过的类型**优先使用插件里的程序**。即使 Windows 把 `.md` 的默认应用改回记事本,右键菜单和“用 Typora 打开”仍然按插件设置执行。 --- ## 安装 在 PowerShell 中运行(不需要管理员权限): ```powershell powershell -ExecutionPolicy Bypass -File "E:\Deepseek Talk\dsh-open-with\install.ps1" ``` 脚本会: 1. 把插件复制到 `%USERPROFILE%\.dsh\profiles\desktop\node_modules\dsh-open-with` 2. 在 profile 的 `package.json` 里登记依赖,并把 `dsh-open-with` 加入 `dsh.profile.bundles` 3. 如果之前装过旧版,会移除 `cordis.patch.yml` 里的手工 entry(bundle 和手工 entry 不能同时存在) 然后**完全退出并重新打开 DeepSeek Harness**(不是刷新页面——bundle 列表变化要重启才生效)。 重启后打开侧栏 **插件**,应该能看到 **dsh-open-with**;点进去就是「默认打开方式」设置页。 > 桌面版的 `desktop` profile 由 Electron 应用独占管理,`dsh plugin --profile desktop add ...` 会被拒绝,所以脚本直接完成“复制包 + 登记 bundle”这两步。 ### 卸载 ```powershell powershell -ExecutionPolicy Bypass -File "E:\Deepseek Talk\dsh-open-with\install.ps1" -Uninstall ``` 然后重启 DSH。 --- ## 配置 Typora(示例) 1. 重启 DSH → **插件** → **dsh-open-with** → 「默认打开方式」。 2. 点 **「打开设置」** 打开宽抽屉(约 1200px;右键菜单「打开方式设置…」会直接打开它)。按 **Esc**、点右上角 **✕** 或点遮罩关闭。 3. 表格默认有一行空行。点这一行的 **扩展名** 格子,在下拉里选 `md`(顶部有类型筛选条:全部 / 常用 / 文档 / 表格 / 演示 / 编程 / 设计图片 / 3D模型 / 配置脚本;输入字母实时过滤;清单外可直接输入)。 4. 点 **应用名称** 格子,下拉会列出 Windows 登记为可打开 `.md` 的应用(Typora、WPS、VS Code、记事本…),系统默认标「系统默认」;选 Typora。 5. 路径自动填好,**自动保存**(标题行右侧显示「已自动保存」)。关闭抽屉后,插件页摘要会显示 `.md → Typora`。 6. 回到对话,右键任意 `.md` 文件卡片,第一项就是 **用 Typora 打开**。 > 推荐列表里没有想要的应用?点下拉底部的「手动填写路径」,或直接在路径格粘贴 exe;路径格右侧的文件夹图标可以浏览选择。 > 如果扩展名在系统里**没有任何登记**,下拉会显示“没有找到可打开 .xxx 的应用”,不会展示 Windows 的通用回退列表;直接在路径格填写即可。 > 查询只针对“该扩展名”的注册信息,不扫描开始菜单/Program Files,不批量读 exe、不批量提图标。 ### 宽抽屉 - 插件页只放摘要;真正的表格在抽屉里,宽度 `min(1320px, 100vw - 280px)`,不再受插件详情页阅读宽度限制。 - 右键「打开方式设置…」会直接打开抽屉;插件页点「打开设置」也可以。 - **Esc**、右上角 **✕**、点击遮罩都能关闭;关闭后回到摘要,自动保存状态和已配置类型会同步显示。 - 抽屉标题行有 **Aa** 缩放:100% / 110% / 120% / 130%,默认 **120%**(约大两号);设置存 `localStorage`,只影响抽屉,不改 DSH 全局字号。 - 抽屉只覆盖当前页面,不改变 DSH 其他页面布局;DSH 升级不会因为父容器 max-width 变化而错位。 ### 新增 / 批量新增 / 批量删除 - **新增**:聚焦或补一行空行;表格最后始终保留一行空行。 - **批量新增**:在抽屉标题下方**展开一块全宽面板**(不是浮层,不会压住表格);勾选多个扩展名(可跨分组,例如 `js` + `doc` + `pdf` + `psd`),一次加多行;可选择一个「统一应用」让所有类型共用同一程序,留空则逐行选。 - **批量删除**:行左侧勾选框选中多行 → 表格上方出现「批量删除」;删除后 6 秒内可「撤销」。 - **自动保存**:没有保存按钮。下拉选择、删除立即保存;路径输入停止 600ms 后保存;只保存“扩展名 + 绝对路径”完整的行。没有选应用的行是编辑中的草稿,不会写进配置,标题行会显示「N 行待完成」。 以后新增类型(`pdf`、`docx`、`txt`…)同样在表格里加一行即可;每行都保留「应用下拉」「路径直接填写」「文件夹图标浏览」三种方式。 ### 扩展名类型筛选 - 扩展名下拉顶部有类型筛选条:**全部 / 常用 / 文档 / 表格 / 演示 / 编程 / 设计图片 / 3D模型 / 配置脚本**。 - 点某个类型只看该类;输入字母会回到「全部」并全局过滤,避免“当前分类下找不到”的困惑。 - 批量新增浮层里也有同样的筛选条。 - 3D/模型组包含:`glb`、`gltf`、`obj`、`stl`、`ply`、`fbx`、`usdz`、`3mf`、`dae`、`3ds`、`blend`、`usd`、`usda`、`usdc`、`abc`、`x3d`、`vrm`、`wrl`、`amf`、`step`、`stp`、`iges`、`igs`、`skp`、`dwg`、`dxf`。 - 设计/图片组包含:`psd`、`ai`、`png`、`jpg`、`jpeg`、`svg`、`webp`。 --- ## 右键菜单行为 | 菜单项 | 行为 | |---|---| | 用 X 打开 | 如果该扩展名在插件设置里配置了应用,直接用它打开;没有配置则回退到系统默认应用 | | 打开方式… | 列出“插件设置”的应用和 Windows 当前关联的应用;勾选「记住」会把所选应用写入插件设置 | | 在文件夹中显示 | 打开资源管理器并选中该文件 | | 复制路径 | 复制完整路径 | | 在侧栏预览 | 打开 DSH 的文档预览 | | 打开方式设置… | 跳到 **插件 → dsh-open-with → 默认打开方式** | 「打开方式…」里的系统应用列表来自 Windows Shell 的文件关联;没有登记时会显示“没有找到可打开 .xxx 的应用”,并保留「在插件设置中配置…」。插件设置里已配置的应用仍然可用。 --- ## 配置存在哪里 - 默认:`%USERPROFILE%\.dsh\open-with.json` - 设置了 `DSH_HOME` 时:`%DSH_HOME%\open-with.json` - 内容示例: ```json { "version": 1, "apps": { "md": { "name": "Typora", "path": "C:\\Program Files\\Typora\\Typora.exe" } } } ``` - 保存时原子写入(临时文件 + rename),不会写坏。 - 这是**插件自己的配置**,与 Windows 的“默认应用”互不影响;Windows 改默认应用不会覆盖它。 - 想重置:在设置页删除对应行(自动保存),或退出 DSH 后删除该 JSON 文件。 --- ## 设计说明 ### 为什么放在插件页,而不是只在右键弹窗里 “哪种文件用哪个程序”是低频、跨文件的设置,放在 **插件 → dsh-open-with** 的独立页面里更合适:可以一次配好多种类型、能从系统登记列表里直接选应用、也能浏览或粘贴 exe。右键里的「打开方式…」保留临时选择和“记住”作为快捷入口,两边写的是同一份配置。 ### 为什么能不受 Windows 默认关联影响 - 配置过的类型,Host 直接 `spawn` 你指定的可执行文件,并把文件路径作为第一个参数传给它,**不经过 Windows 的 `ShellExecute` 关联解析**。 - 只有“没有配置”的类型才回退到 DSH 原有的系统默认打开链路。 - Host 在打开前会校验:路径是绝对路径且能通过 DSH 文件系统映射;配置的程序文件存在;不会接受请求里临时传来的任意 exe——exe 只能来自插件配置。 ### 安全边界 - 四个路由(`/open-with/config`、`/open-with/open`、`/open-with/browse`、`/open-with/handlers`)都先经过 `connection.requestRejection`:Host/Origin 防跨站 + 浏览器登录 cookie 鉴权,和 DSH 自带的 open-in-app 路由同一套围栏。 - `/open-with/handlers` 只做“单个扩展名已登记处理器”的只读查询(复用 `@deepseek-ai/dsh-native-command`),按扩展名缓存 5 分钟;不扫开始菜单、不遍历 Program Files、不批量读 exe。 - 查询前先用 `reg.exe` 检查 `HKCR\.` 是否存在;不存在时直接返回空,避免 Windows 对未登记类型返回的通用“打开方式”列表混进来。 - 配置写入限制大小(64 KiB)和条数(200),扩展名只允许字母/数字/下划线/加号/减号,路径必须是绝对路径。 - 启动子进程时清理环境变量中的 token/secret/password 等敏感项,使用 `detached + stdio: ignore`,不阻塞 Host。 ### 文件结构 ``` dsh-open-with/ ├─ package.json # dsh.client.platform = web;dsh.bundle.patch ├─ cordis.patch.yml # bundle 的 entry(- insert:) ├─ lib/ │ ├─ index.js # Host:配置读写、打开、浏览对话框、按扩展名查登记应用 │ └─ client.js # 浏览器:右键菜单、打开方式弹窗、插件设置页与应用选择器 ├─ install.ps1 └─ README.md ``` 客户端 bundle 是手写的 `window.__ModuleLoader__.load({ id, factory })`,只依赖平台模块表里的 `react`、`react-dom` 和 `@deepseek-ai/dsh-client-store`,不需要构建步骤。 --- ## 限制 - 配置的程序会收到 `程序路径 "文件路径"` 这种单参数调用;需要特殊参数的程序(例如 `code -g file:line`)暂不支持。 - 应用下拉只列 Windows 已登记为该扩展名处理器的应用;没登记时不会显示 Windows 的通用回退列表,而是提示没有找到,直接在路径格填写即可。 - 应用下拉没有可用应用时:行保留为编辑中的草稿,不写配置;只有路径是绝对路径后才会自动保存。 - 从“打开方式…”里选 UWP/打包应用时,系统返回的可能是 AUMID 而不是 `.exe` 路径,这种应用无法写入插件配置;请用文件夹图标浏览具体 exe。 - 路径格的文件夹图标目前只在 Windows 上弹出文件选择框;macOS/Linux 可以手动填写绝对路径。 - 文件必须能通过 DSH 的文件系统映射(通常是会话工作区里的文件);映射不到的外部路径会被拒绝。 - 只在有本地桌面的部署里生效(Web/Desktop Host)。纯远程部署没有本地程序可启动。 --- ## 排错 | 现象 | 处理 | |---|---| | 插件页里没有 dsh-open-with | 先**完全重启** DSH;检查 `%USERPROFILE%\.dsh\profiles\desktop\package.json` 的 `dsh.profile.bundles` 是否包含 `dsh-open-with`,以及 `node_modules\dsh-open-with` 是否存在 | | 右键没有自定义菜单 | 确认插件页里 dsh-open-with 是启用状态;重启 DSH;检查 `lib/client.js` 是否被加载(Settings → 插件列表会显示加载失败) | | 右键第一项还是“系统默认” | 该扩展名没有在插件设置里保存;检查扩展名是否写成了 `.md`(不要带点)或大小写不一致(会统一转小写) | | 应用下拉为空或读取失败 | 该扩展名在系统里没有登记处理器,或查询被安全软件拦住;直接在路径格粘贴 exe,或点文件夹图标浏览 | | 应用下拉提示没有找到 | 这个扩展名没有登记任何程序;在路径格手动填写,或先在本机安装/关联一个程序 | | 「打开方式…」显示“无法读取本机应用列表” | 该路径没有通过 Host 文件映射,或 Windows 关联查询失败;直接在插件设置页用路径格手动配置 | | 选 Typora 打开失败 | Typora 路径变了或被卸载;在设置页用文件夹图标重新选一次 | | 自动保存没生效 | 看标题行是否显示“已自动保存”;缺应用或路径的草稿行不会写入;重启 DSH 后草稿不保留 | | 想恢复系统默认 | 在设置页删除该扩展名(自动保存);或右键「打开方式…」选系统应用但不勾“记住” | 安装脚本写入前会备份 `package.json` 和 `cordis.patch.yml`,文件名带 `bak-时间戳`,出问题可以还原。 --- ## 兼容性 基于 DSH `0.2.1-rc.5` 的客户端槽位(`shell.overlay`、`plugins.bundle.config`)、Session Remote 与 `webServer` 路由开发。DSH 升级后若这些接口变化,需要同步调整 `lib/client.js` / `lib/index.js`;升级重建 profile 后重跑一次 `install.ps1`。 --- ## 开发与发布 ```powershell # 开发模式:把源码链接进 profile,改完刷新页面或重启 DSH powershell -ExecutionPolicy Bypass -File .\install.ps1 -Link # 构建发行包:dist\dsh-open-with-v.zip + SHA256SUMS.txt powershell -ExecutionPolicy Bypass -File .\scripts\build-release.ps1 ``` - 版本号写在 `package.json`;发版前更新 `CHANGELOG.md`。 - tag 用 `v`;Release 附上 `dist\dsh-open-with-v.zip` 和 `安装与使用说明.pdf`。 - `INSTALL.md` 改动后需要重新生成 PDF(Edge 打印 HTML),再更新 Release 附件。