Bug:Web UI 原生文件夹选择器不置前;服务孤儿化时选择器崩溃(附已验证修复) #1503
Zhangbo-cn
started this conversation in
General
Replies: 2 comments
|
Windows 文件夹选择器不置前 + 孤儿化崩溃——选择器是 #800(中文路径截断)那个组件的另一个问题面。 带已验证修复很好,建议连同 #800 的 readUtf16 修复一起提给官方。Windows 路径/选择器坑位第 12 章有汇总:https://github.com/Electricitysheep/dsh-handbook/blob/main/docs/12-limitations.md |
0 replies
|
感谢维护者的反馈与关联问题提示(选择器是中文路径截断那个组件的另一面)。已按建议一并补充:
Windows 路径/选择器坑位已参考 dsh-handbook 第 12 章(#107 根因帖)。若官方开放 PR,随时可合并。 |
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.
Uh oh!
There was an error while loading. Please reload this page.
一句话
Windows 下 Web UI 触发的原生文件夹选择器有两个问题:① 对话框出现在浏览器窗口后面、不置前,需要手动点任务栏;② 当
dsh web服务进程孤儿化(所属终端/后台任务被关闭)后,选择器直接失败,报win32 folder dialog worker exited before reporting a result。复现
pnpm dsh web,打开 Web UIhttp://127.0.0.1:3080。host.pickDirectory→ 原生IFileOpenDialog目录选择器)。实际结果
directory picker failed: win32 folder dialog worker exited before reporting a result。给 worker 加生命周期日志发现:子进程在 JS 顶层代码执行前(CRT 启动阶段)即退出,stdout/stderr 无任何输出。同一代码在正常启动的服务上,选择器工作正常。预期结果
环境
根因
packages/host/directory-picker-native以IFileOpenDialog::Show(NULL)(无 owner 窗口)打开对话框。对话框子进程由服务端 spawn,并非用户直接输入来源,Windows 前台锁(foreground lock)限制其无法主动抢到前台,于是落在浏览器后面。代码注释假设"子进程的第一个窗口 Windows 会自动激活",但由浏览器触发的场景下不可靠。spawnDialogWorker用stdio: ['ignore','inherit','inherit','ipc']spawn 对话框子进程。当父进程(dsh web服务)孤儿化后,其 console/stdio 句柄在 Windows 上已失效;子进程继承这些句柄后,CRT 启动校验失败、任何 JS 未执行即终止,父进程只收到exit事件 → 报 "worker exited before reporting a result"。修复(已验证)
// packages/host/directory-picker-native/src/win32-dialog-bindings.ts const getCurrentThreadId = kernel32.func('__stdcall', 'GetCurrentThreadId', 'uint32', []) + const getForegroundWindow = user32.func('__stdcall', 'GetForegroundWindow', 'void *', []) ... - show: () => method(dialog, SLOT_SHOW, protoShow)(null), + show: owner => method(dialog, SLOT_SHOW, protoShow)(owner), ... + foregroundWindow: () => getForegroundWindow() as number,修复 ① 的原理:把当前前台窗口(用户刚点击的浏览器)作为 owner 传给
Show,带 owner 的模态对话框会被 Windows 显示在 owner 之上并自动激活。对话框结果本就通过 IPC 回报,不依赖父进程 stdio,故 ② 直接固定子进程 stdio 为 NUL 即可。关联问题:中文路径截断(readUtf16)
感谢维护者的反馈——本组件还涉及中文路径截断问题(官方讨论区 dsh-handbook 第 12 章 汇总,根因帖 discussion #107,家族 17+ 帖):
readUtf16以单字节判 0 作为终止符,遇到 UTF-16 单元低字节为0x00的字符(如开=U+5F00 → UTF-16LE00 5F)会误判终止、截断路径。已一并修复并加回归测试:验证
pnpm exec vitest run packages/host/directory-picker-native/tests→ 47 passed / 1 skipped(5 个文件)。补丁分支
完整补丁(前台置前 + 孤儿化健壮性 + readUtf16 中文路径)已提交到 fork 的
fix/win32-directory-picker分支:https://github.com/Zhangbo-cn/deepseek-harness/tree/fix/win32-directory-picker(若官方后续开放 PR,可直接从该分支创建)。All reactions