摆脱 ShellExecute 造成的邪恶延迟
Posted
技术标签:
【中文标题】摆脱 ShellExecute 造成的邪恶延迟【英文标题】:Getting rid of the evil delay caused by ShellExecute 【发布时间】:2008-10-07 08:13:55 【问题描述】:这是困扰我一段时间的事情,必须有一个解决方案。每次我调用 ShellExecute 打开一个外部文件(无论是文档、可执行文件还是 URL)时,都会在 ShellExecute 生成新进程并返回之前在我的程序中造成很长时间的锁定。有谁知道如何解决或解决这个问题?
编辑:正如标签所示,这是在使用 C++ 的 Win32 上。
【问题讨论】:
【参考方案1】:我不知道是什么原因造成的,但是 Mark Russinovich(以 sysinternal 闻名)有一个非常棒的博客,他解释了如何调试这些事情。 The Case of the Delayed Windows Vista File Open Dialogs 是一个不错的选择,他只使用进程资源管理器调试了一个类似的问题(结果是访问域时出现问题)。你当然可以使用常规的 Windows 调试器来做类似的事情。
您的问题可能与他的不同,但使用这些技术可能会帮助您更接近问题的根源。我建议调用 CreateProcess
调用,然后捕获一些堆栈跟踪并查看它似乎挂起的位置。
The Case of the Process Startup Delays 可能更适合您。
【讨论】:
【参考方案2】:你是多线程的吗?
我发现使用 ShellExecute 打开文件时出现问题。不是可执行文件,而是与应用程序相关的文件 - 通常是 MS Office。使用 DDE 打开文件的应用程序向所有线程(好吧,我不知道它是否是所有 ...)程序中的所有线程进行了一些消息广播。因为我没有在我的应用程序的工作线程中发送消息,所以我会挂起 shell(以及文件的打开)一段时间。它最终超时等待我处理消息,应用程序将启动并打开文件。
我记得在循环中使用 PeekMessage 来删除该工作线程队列中的消息。我一直认为有办法以另一种方式避免这种情况,也许以不同的方式创建线程以使其永远不会成为消息的目标?
更新 它一定不仅仅是任何线程在执行此操作,而是一个为窗口提供服务的线程。 雷蒙德(link 1) 知道所有(link 2)。我敢打赌 CoInitialize(单线程单元)或 MFC 中的某些东西为线程创建了一个隐藏窗口。
【讨论】:
因此意味着在客户端机器上运行的潜在任何应用程序可能会导致这样的延迟?谈论一个无用的 API。 :( 更新了更多信息。我在 1996-1997 年的某个时候遇到过这个问题,所以我花了一段时间才真正记住整个问题。在 Raymond Chen 的帮助下。 如果一个线程有一个窗口,它必须泵送消息——这是在窗口中编程合同的一部分以上是关于摆脱 ShellExecute 造成的邪恶延迟的主要内容,如果未能解决你的问题,请参考以下文章
如何利用ShellExecute()函数,从后台打开一个网页