摆脱 ShellExecute 造成的邪恶延迟

发布于 2024-07-07 00:53:01 字数 188 浏览 10 评论 0原文

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

编辑:正如标签可能表明的那样,这是在使用 C++ 的 Win32 上。

This is something that's been bothering me a while and there just has to be a solution to this. Every time I call ShellExecute to open an external file (be it a document, executable or a URL) this causes a very long lockup in my program before ShellExecute spawns the new process and returns. Does anyone know how to solve or work around this?

EDIT: And as the tags might indicate, this is on Win32 using C++.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

只是在用心讲痛 2024-07-14 00:53:02

你是多线程的吗?

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

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


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

Are you multithreaded?

I've seen issues with opening files with ShellExecute. Not executables, but files associated an application - usually MS Office. Applications that used DDE to open their files did some of broadcast of a message to all threads in all (well, I don't know if it was all...) programs. Since I wasn't pumping messages in worker threads in my application I'd hang the shell (and the opening of the file) for some time. It eventually timed out waiting for me to process the message and the application would launch and open the file.

I recall using PeekMessage in a loop to just remove messages in the queue for that worker thread. I always assumed there was a way to avoid this in another way, maybe create the thread differently as to never be the target of messages?


Update
It must have not just been any thread that was doing this but one servicing a window. Raymond (link 1) knows all (link 2). I bet either CoInitialize (single threaded apartment) or something in MFC created a hidden window for the thread.

夜灵血窟げ 2024-07-14 00:53:02

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

您的问题可能与他的不一样,但是使用这些技术可能会帮助您更接近问题的根源。 我建议调用 CreateProcess 调用,然后捕获一些堆栈跟踪并查看它似乎挂起的位置。

进程启动延迟的情况可能是均匀的与您更相关。

I don't know what is causing it, but Mark Russinovich (of sysinternal's fame) has a really great blog where he explains how to debug these kinds of things. A good one to look at for you would be The Case of the Delayed Windows Vista File Open Dialogs, where he debugged a similar issue using only process explorer (it turned out to be a problem accessing the domain). You can of course do similar things using a regular windows debugger.

You problem is probably not the same as his, but using these techniques may help you get closer to the source of the problem. I suggest invoking the CreateProcess call and then capturing a few stack traces and seeing where it appears to be hung.

The Case of the Process Startup Delays might be even more relevant for you.

天邊彩虹 2024-07-14 00:53:02

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

I also recently found an issue around ShellExecute. I was able to determine that ShellExecute will drop messages from the Window Message Queue. I've submitted a question about it here. It's possible this could explain why your program has delays. ShellExecute is probably dropping messages from the queue because it's calling GetMessage or PeekMessage itself and could be dropping messages that are meant for your window needed to be able to respond. For me I've solved the issue by using "CreateProcess" with "cmd.exe /c start ..." instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文