【问题标题】:ShellExecuteEx on windows 7 with default image / photo viewer带有默认图像/照片查看器的 Windows 7 上的 ShellExecuteEx
【发布时间】:2013-03-19 12:48:14
【问题描述】:

我们有一个在 Windows XP、Windows Vista、Windows 7 等上运行的桌面应用程序(它是用 cobol 编写的,但我认为在这种情况下它不相关)。

在我们的源代码中,我们使用open 调用ShellExecuteEx。
在这之后——为了等待被调用程序的终止——我们用infinite调用WaitForSingleObject。

它没有问题,只有在带有图像的 windows-7 机器上和我们的默认图像查看器有问题。

如果为 jpg 或 tif 文件调用 ShellExecuteEx 并且机器只有默认的 windows 图像/照片查看器,则会发生错误。 WaitForSingeObject 返回 WAIT_FAILED 和 GetLastError() 说:INVALID_HANDLE。

当有另一个图像查看器(例如 Picasa 照片查看器或 Evince windows 版本或 JPEGView)时,这不会在 Windows 7 上发生。

我不知道 Windows 7 和 ShellExecuteEx 上的默认图像查看器的问题出在哪里。 ShellExecuteEx 不返回错误代码!

非常感谢。

更新: 谢谢你的回答。

@大卫赫弗南: 正如您所说,在它不起作用的情况下,ShellExecuteEx 的返回码 (hInstApp) 为 42(好的!)并且 hProcess 为 NULL! (唯一启动的新进程是 dllhost.exe。)

但是,我在另一台 Windows 7 机器上测试了整个过程。在这种情况下,我做了以下事情:
- 在这台机器上,Picasa 是默认查看器。
- 我切换回默认设置(Windows 照片查看器)。
- 成功了!
- 然后我没有关闭照片查看器并在我们的应用程序中再次按下“显示”。 - 即使 Windows 照片查看器已经在运行,它也可以工作(弹出一个新的查看器实例)!

【问题讨论】:

  • 您确定 ShellExecuteEx 没有返回错误吗?即使按照 Windows API 的标准,它的错误处理也特别不透明——你最终不得不将结构的 hInstApp 成员转换为 int 并将其与 32 进行比较。它在结构的 hInstApp 成员中存储了什么值失败案例?
  • 你还在等什么?你能给我们看看那个代码吗?
  • @DavidK 你很困惑。你在想ShellExecute。事实上,ShellExecuteEx 确实提供了不错的错误报告。
  • @Wolfgang 关于您的更新,这很有趣,但不会改变您提出的问题的答案。
  • @WolfgangAdamec 我认为尝试检测它是不现实的。 ShellExecuteEx 电话的另一端几乎可以有任何东西。就个人而言,我倾向于向您的应用程序添加一个简单的图像查看器,以便您可以控制 UI。总的来说,您试图与 shell 实现的交互是您无法控制的。

标签: winapi windows-7


【解决方案1】:

现代 Windows 版本中图像上 open 动词的默认处理程序可能不会调用新进程。它很可能只是在已经运行的 shell 进程中显示图像。发生这种情况时,返回的进程句柄是NULL。这就是这里发生的事情,这就是为什么对WaitForSingleObject 的调用以您描述的方式失败。

SHELLEXECUTEINFO 的文档包含以下内容:

即使 fMask 设置为 SEE_MASK_NOCLOSEPROCESS,如果没有启动进程,hProcess 也会为 NULL。例如,如果要启动的文档是 URL,并且 Internet Explorer 的实例已经在运行,它将显示该文档。没有新进程启动,hProcess 将为 NULL。

这一切的意思是,你的程序那部分的设计是基于一个有缺陷的假设。即假设调用ShellExecuteEx 将始终产生一个进程句柄,您可以在该句柄上等待终止。您将需要找到其他方法来解决您的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多