摆脱ShellExecute造成的邪恶延迟

问题描述 投票:0回答:3

这是困扰我一段时间的事情,必须有一个解决方案。每次我调用 ShellExecute 打开外部文件(无论是文档、可执行文件还是 URL)时,这都会导致我的程序在 ShellExecute 生成新进程并返回之前出现很长时间的锁定。有谁知道如何解决或解决这个问题?

编辑:正如标签所示,这是使用 C++ 在 Win32 上进行的。

c++ winapi shellexecute
3个回答
9
投票

我不知道是什么原因造成的,但是 Mark Russinovich(以 sysinternal 闻名)有一个非常棒的博客,他在其中解释了如何调试此类事情。您可以看看Windows Vista 文件打开对话框延迟的案例,其中他仅使用进程资源管理器调试了类似的问题(结果是访问域的问题)。您当然可以使用常规 Windows 调试器执行类似的操作。

您的问题可能与他的不一样,但是使用这些技术可能会帮助您更接近问题的根源。我建议调用

CreateProcess
调用,然后捕获一些堆栈跟踪并查看它似乎挂在哪里。

流程启动延迟的案例可能与您更相关。


3
投票

你是多线程的吗?

我发现使用 ShellExecute 打开文件时出现问题。不是可执行文件,而是与应用程序关联的文件 - 通常是 MS Office。使用 DDE 打开文件的应用程序会向所有(好吧,我不知道是否是all...)程序中的所有线程广播一些消息。由于我没有在应用程序的工作线程中泵送消息,因此我会将 shell(以及文件的打开)挂起一段时间。最终在等待我处理消息并且应用程序启动并打开文件时超时。

我记得在循环中使用 PeekMessage 来删除该工作线程队列中的消息。我一直认为有一种方法可以用另一种方式来避免这种情况,也许以不同的方式创建线程,以免成为消息的目标?


更新 它一定不只是任何正在执行此操作的线程,而是为窗口提供服务的线程。 雷蒙德(链接1)知道一切(链接2)。我打赌 CoInitialize(单线程单元)或 MFC 中的某些内容为线程创建了一个隐藏窗口。


0
投票

我最近还发现了一个有关 ShellExecute 的问题。我能够确定 ShellExecute 将从 Window 消息队列中删除消息。我已在here提交了有关此问题的问题。这可能可以解释为什么你的程序有延迟。 ShellExecute 可能会从队列中删除消息,因为它本身正在调用 GetMessage 或 PeekMessage,并且可能会删除需要能够响应的窗口的消息。对我来说,我已经通过使用“CreateProcess”和“cmd.exe /c start ...”解决了这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.