Repository navigation
[Bug] Windows「打开方式」选中某些应用后,associations.ps1 助手进程永久挂起,界面卡在「正在打开…」 #10369
Tristanash
started this conversation in
General
Replies: 0 comments
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「打开方式」选中某些应用后,associations.ps1 助手进程永久挂起,界面卡在「正在打开…」
环境
0.2.1-rc.2(@deepseek-ai/dsh-desktop)19045.6466(x64)master分支,packages/util/native-command/src/file-applications-windows.ts复现步骤
.cmd和一个.ps1。Fix-Proxy.cmd→ Adobe Premiere Pro CC 2019Fix-Proxy.ps1→ Sublime Text实际结果
两进程的父进程均为
DeepSeek Harness.exe,CPU 累计仅约 0.3 s(在等,不是在忙循环)。StaticWindow Dialogpowershell.exe助手IsWindowVisible = true,出现在任务栏,点击无反应注意:
windowsFileApplications()是用'hidden'窗口样式启动这个 helper 的,所以这个可见窗口不是控制台窗口,而是 COM/消息泵路径上产生的。对照实验
.cmd.ps1.ps1/.cmd即:同样的文件、同样的调用链,只换 handler 结果就不同。所以不是文件本身的问题,也不是 ShellExecute 层面的关联损坏(
HKCR\.cmd为标准的cmdfile,ftype cmdfile="%1" %*)。根因分析
Open()的路径是:OpenRegistered内部命中目标 handler 后调用handler.Invoke(data),随后进入WithShellLifetime的排空循环(file-applications-windows.ts:93-97附近):这个循环的设计意图是「等 Shell 的异步启动真正释放宿主」,判断依据是
SHCreateThreadRef的计数回落到基线。问题在于退出条件完全依赖对端:Invoke本身阻塞在等待应用握手/模态窗口上),这个while就永久成立,GetMessage靠 10ms 的WM_TIMER反复唤醒,进程既不退出也不报错。run(...)只接受signal(取消),UI 既然一直显示「正在打开…」,说明这层也没有基于时长的兜底;于是 helper 永远不返回,卡片状态永久挂起。'hidden'启动的,用户连它在干什么都看不到,只会看到任务栏多出一个点不开的Window Dialog。Stop-Process才清掉)。至于「为什么偏偏是这两个应用」,我这里只能给出观察,不敢断言机制:两者都是长期驻留的 GUI 进程,且都通过 shell 注册的 handler 启动;记事本则是经典 Win32「open」动词。要区分「
Invoke未返回」与「Invoke返回了但引用计数未回落」,需要 helper 侧打点(见下)。建议修复
run(...)外层,如 15 s),超时killhelper 并把错误回抛 UI,让卡片显示「打开失败」而不是永久「正在打开…」。ShellExecuteEx(SEE_MASK_NOASYNC)按 ProgID/exe 启动,避免走IHandler::Invoke后再等引用计数。保留Invoke作为「打包应用 / DDE」的回退路径。count当前值与 handler 名,方便定位是哪个 handler 不放引用。需要的话我可以提供
Win32_Process的CommandLine/ParentProcessId)associations.ps1的原始内容(含解码后的path/application)Invoke前后 + 每次count变化),可以按你说的方向精确定位是「Invoke不返回」还是「计数不回落」English summary
On Windows, after picking a handler in the file-card "Open" menu,
associations.ps1can hang forever for some applications.
Open()callsIHandler::InvokeinsideWithShellLifetime, whose drain loop (while (ReadInt32(count) > owned) { GetMessage(...) })has no deadline, and the caller (
run(...)) has no timeout either. When the chosenhandler never releases the shell thread reference, the helper process never exits: the UI
stays on "Opening…" indefinitely, a visible
Window Dialogtop-level window (classStatic) is left in the taskbar, and the process survives even after the app is closed.Choosing Notepad for the same file returns immediately and leaves nothing behind.
Fixes: bound the drain loop with a deadline, add a caller-side timeout that kills the
helper and surfaces the error, prefer
ShellExecuteExfor non-packaged handlers, and cleanup orphaned helpers on app exit.
All reactions