Skip to content
dsh.fish
Bundle

dsh-reveal-fix

Fix DSH's "reveal in file manager" on Windows: Explorer opened at Desktop, and windowsHide:true created the window hidden (SW_HIDE).

Source
HeJian2002W
License
MIT
Updated
Updated 10 hours ago

Readme

# dsh-reveal-fix

修复 DSH 在 Windows 上「在文件资源管理器中显示」失效的问题。**以用户插件形式实现,因此不受 dsh 升级影响。**

## 症状

点击交付卡片上的「在文件资源管理器中显示」时:

- 接口返回 HTTP 204,界面提示「已请求在文件资源管理器中显示」
- **但屏幕上什么都不出现** —— 没有窗口、没有任务栏闪烁、没有报错

UI 报告成功,用户感知为零,且没有任何可供诊断的痕迹。

## 根因(上游两个独立缺陷叠加)

| # | 缺陷 | 后果 |
|---|---|---|
| **A** | `revealNativePath()` 把 `pathToFileURL().href`(百分号编码的 `file:` URL)交给 `explorer.exe /select,`,而它接受的是**文件系统路径** | Explorer 无法解析,**静默回退打开「桌面」**。空格 → `%20`,非 ASCII → `%E5%89%8D...` |
| **B** | 共享 runner 硬编码 `windowsHide: true`,Node 将其转为 STARTUPINFO 的 `wShowWindow = SW_HIDE`,explorer.exe 把这个显示状态应用到它新建的窗口 | 窗口**被创建成隐藏**:`IsWindowVisible()` 返回 `false`,永不显示 |

**为什么无法诊断**:Explorer 无论成败退出码恒为 1(上游将其视为"已委派"吞掉);HTTP 路由恒返回 204;前端提示文案与成功时完全相同。三者叠加使故障完全静默。

## 本插件的做法

在 `sessionController` 上替换 `revealPath`:

- 传**纯 Windows 路径**(单个 argv 元素,紧贴逗号)
- `windowsHide: false`,让窗口真正显示
- 非 Windows 平台回退到原实现
- 保留上游约定:Explorer 退出码 1 不视为失败

`sessionController.openWorkspacePath()` 内部是 `await this.revealPath(...)` **动态查找**,因此在实例上替换方法即可生效,**无需修改任何核心文件**。

## 安装

**从 GitHub 安装(推荐):**

```powershell
dsh plugin --profile web add github:HeJian2002W/dsh-reveal-fix
```

**从本地目录安装(离线 / 自己改代码时):**

```powershell
dsh plugin --profile web add link:C:\Users\Admin\.dsh\local-plugins\dsh-reveal-fix
```

安装后**重启 dsh** 生效。

卸载:

```powershell
dsh plugin --profile web remove dsh-reveal-fix
```

## 为什么不受升级影响

- 插件源码位于 `~/.dsh/local-plugins/`,注册信息位于 `~/.dsh/profiles/web/`
- 两者都在 **dsh 安装目录之外**;升级(temp 暂存 → 目录交换)不会触及
- 与核心安装 `node_modules` 里的手工改动不同,升级后无需重新打补丁

> 前提:上游若改变 `sessionController.revealPath` 的名字或语义,本插件需要同步更新。
> 因此仍建议把缺陷提给上游(`@deepseek-ai/dsh-native-command`),长期方案是修在源头。

## 验证

判定标准不是「窗口计数增加」——`Shell.Application.Windows()` **会列出隐藏窗口**,计数无法区分可见与否。必须查 `IsWindowVisible`:

```powershell
Add-Type -MemberDefinition '[DllImport("user32.dll")] public static extern bool IsWindowVisible(IntPtr h);' -Name W -Namespace Q
(New-Object -ComObject Shell.Application).Windows() |
  ForEach-Object { "{0,-6} {1}" -f [Q.W]::IsWindowVisible([IntPtr]$_.HWND), $_.LocationURL }
```

修复前:目标目录窗口存在但 `visible=False`。
修复后:`visible=True`。

独立 A/B(同一命令,仅改一个变量):

| 变量 | 结果 |
|---|---|
| `pathToFileURL().href` → `/select,` | 窗口落在 `Desktop` ❌ |
| 纯路径 → `/select,` | 窗口落在目标目录 ✅ |
| `windowsHide: true` | `IsWindowVisible = False` ❌ |
| `windowsHide: false` | `IsWindowVisible = True` ✅ |

## 已知残留(本插件不处理)

两个缺陷都修好后,浏览器仍会在约 **1.7 秒**后把前台焦点抢回(即使服务端调用 Win32 `SetForegroundWindow` 强制置顶,同样在 1.7s 内被覆盖),窗口容易被压在浏览器后面。

若要改善,可在 reveal 后延迟约 2s 再断言一次前台。**默认不启用**:这会引入「用户已切去做别的事、窗口突然跳出来抢焦点」的副作用,属产品行为取舍。

Install

dsh plugin --profile web add github:HeJian2002W/dsh-reveal-fix

Profile: web

  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source