Repository navigation
Replies: 1 comment
|
同症状第三台机器的实证补充:这个现象与 #11020 是同一个根因—— 本机证据(DSH 桌面版 0.2.2-rc.3,Windows 11,Medium IL、非沙箱的普通
修复建议与 #11020 一致:在 |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
[BUG][Windows] 文件「打开方式」菜单始终显示「无法获取应用列表」(
SHAssocEnumHandlers→E_FAIL)0.2.2-rc.1@deepseek-ai/dsh-client-ui-open-in-app、@deepseek-ai/dsh-native-command、@deepseek-ai/dsh-api-session-controller概要
任意文件卡片(聊天里的交付文件、文件树、文档标题栏)点开右侧下拉箭头后,菜单里没有可用的应用列表,只有一条置灰的「无法获取应用列表」,底部是「显示文件位置(默认)」。
这不是文件本身或系统关联的问题:同一个
.html双击能正常用 Edge 打开,HKCU\...\FileExts\.html\UserChoice=MSEdgeHTM且哈希有效。失败发生在 Host 枚举「能打开该扩展名的应用」这一步:Windows Shell 的SHAssocEnumHandlers返回E_FAIL (0x80004005),客户端因此把整个列表判为失败。复现步骤
残疾人证管理系统.html)。期望 / 实际
根因分析
客户端链路
packages/client/ui-open-in-app/src/client/open-path.ts—OpenInAppPathController.applications()调session.workspacePathApplications({ path });RPC 抛错或ok === false时返回null。@deepseek-ai/dsh-client-ui-open-in-app(client/file-applications.ts)—subscribe()里failed: apps === null。packages/client/ui-open-in-app/src/client/OpenTargetButton.tsx—failed为真时渲染t("path.appsError")(即「无法获取应用列表」),且revealDefault生效,主按钮变成「显示文件位置」。也就是说:任何 RPC 失败(路径校验失败、取消、原生查询失败)都会折叠成同一句文案,用户无法区分。
Host 链路
packages/api/session-controller/src/index.ts—workspacePathApplications()内this.fileApplications(path, signal)抛错时统一包装为RemoteError("gateway/internal", "file application query failed", { cause })。@deepseek-ai/dsh-native-command(file-applications.ts)—queryFileApplications()在win32上调用windowsFileApplications(target.path, null, signal, run)。@deepseek-ai/dsh-native-command(file-applications-windows.ts)— 起一个powershell.exe -NoProfile -NonInteractive -STA -ExecutionPolicy Bypass -File associations.ps1,脚本Add-Type一段 C#,再由SHAssocEnumHandlers(extension, 0, out handlers)枚举处理器并提取图标。关键证据
用与上面第 3 步相同的 P/Invoke 逻辑(只保留枚举,去掉图标提取)在 DSH 会话进程上下文里运行,
.html失败:替换扩展名后结果相同 ——
.html/.txt/.pdf/.png/.md/.docx全部0x80004005,说明不是某个扩展名的关联损坏,而是枚举调用在本进程上下文里整体不可用。同一台机器上:
Add-Type编译成功(该 C# 源码本身没问题),失败点只在SHAssocEnumHandlers。系统关联侧正常(默认程序存在、双击可打开)。推断的触发条件
执行该查询的子进程处于 Low 完整性级别(受限令牌,S-1-16-4096)。Windows 对跨完整性级别的 COM 激活有限制,Shell 的关联枚举在受限上下文里会直接
E_FAIL。DSH 的 Windows 沙箱(dsh-sandbox-local)正是把受限子进程降到 Low IL 的,因此这里怀疑:两种情况的表现一致:
windowsFileApplications必然失败 → 菜单只剩「显示文件位置」。最小复现
完整脚本见文末(另存为
repro-win-file-associations.ps1后运行;无第三方依赖,ASCII,PS 5.1 可跑):输出里会打印当前用户、完整性标签、PowerShell 版本和枚举结果;失败时以退出码 1 结束并打印 HRESULT。
建议修复(任选其一,1 为推荐)
AssocQueryString(ASSOCF_NONE, ASSOCSTR_EXECUTABLE / ASSOCSTR_FRIENDLYAPPNAME / ASSOCSTR_DEFAULTICON, ".html", ...)加上注册表枚举
HKCU\Software\Classes\.ext\OpenWithProgids、HKCR\.ext\OpenWithList、HKCR\SystemFileAssociations\.ext。这些在低完整性下可读,且不需要激活 Shell 的关联 COM 服务器。图标可对
ASSOCSTR_DEFAULTICON指向的 exe/dll 用SHDefExtractIcon取(纯 Win32,不涉及跨完整性激活)。windowsFileApplications的 PowerShell 调用放到未受限的 Host 子进程(不经 sandbox confine),保留现有 C# 实现。workspacePathApplications失败时携带code/hresult,客户端菜单显示「打开方式查询失败(0x80004005)· 重试」,而不是笼统的「无法获取应用列表」。ShellExecuteEx/start),而不是只剩「显示文件位置」——后者需要用户再去资源管理器里双击,多一步且违背按钮的直觉。影响面
所有在 Windows 上以受限令牌运行 Host(或系统策略阻止跨完整性 COM 激活)的用户:文件「打开方式」菜单不可用,只能走「显示文件位置」。会话本身、文件预览、文件树都不受影响。
临时规避(用户侧)
repro-win-file-associations.ps1(完整脚本)
All reactions