如何查找是不是可以通过 ShellExecute 打开文档?

Posted

技术标签:

【中文标题】如何查找是不是可以通过 ShellExecute 打开文档?【英文标题】:How to find if an document can be OPENed via ShellExecute?如何查找是否可以通过 ShellExecute 打开文档? 【发布时间】:2009-08-12 09:15:10 【问题描述】:

我想检查特定文件是否可以通过 ShellExecute 成功“打开”,所以我尝试使用 AssocQueryString 来发现这一点。

例子:

DWORD size = 1024;
TCHAR buff[1024];  // fixed size as dirty hack for testing

int err = AssocQueryString(0, ASSOCSTR_EXECUTABLE, ".mxf", NULL ,buff , &size);
openAction->Enabled  = ((err == S_OK) || (err == S_FALSE)) && (size > 0);

现在,这几乎可以工作了。如果有注册的应用程序,我会得到字符串。

但是,有一个问题:在Vista上,即使没有注册的应用程序,它返回的应用程序c:\Windows\System32\shell32.dll是关联的,这就是导致100%无用的东西“ Windows 无法打开此文件:Use the Web service to find the correct program?"对话。

显然,我想对最终用户隐藏 cr*p 的部分,但简单地将返回的字符串与常量进行比较似乎是一种丑陋、暴力和脆弱的做法。

此外,入侵注册表以完全禁用此对话框也不是一个好主意。

什么是更好的选择?

【问题讨论】:

【参考方案1】:

我总是使用FindExecutable() 来获取给定文档的注册应用程序。

【讨论】:

谢谢 - 完美运行,如果没有注册应用程序,则会正确“失败”。踢自己没有找到这个...... 由于 Samba 性能问题,不得不重新审视这一点。在下面发布了我现在正在使用的答案。【参考方案2】:

还有另一种方法可以做到这一点,将ASSOCF_INIT_IGNOREUNKNOWN 选项标志与AssocQueryString() 结合使用。

int err = AssocQueryString(ASSOCF_INIT_IGNOREUNKNOWN, ASSOCSTR_EXECUTABLE, ".mxf", NULL ,buff , &size);

与使用FindExecutable()相比,这有几个重要的优势

它可以只使用文件扩展名,而FindExecutable 需要指定类型的现有文件的完整路径。 因为它不访问文件,所以使用 Samba 和其他网络存储会快得多。在我的测试中,通过 Samba 对包含约 3000 个文件的目录中的一个文件调用 FindExecutable() 耗时超过 1 秒。

【讨论】:

我很困惑。你最初说你在使用 Vista 时遇到了问题,现在你说你有一个使用 ASSOCF_INIT_IGNOREUNKNOWN 标志的可行解决方案,根据 MSDN,它是在 Windows 7 中引入的。msdn.microsoft.com/en-us/library/windows/desktop/… 是的,AssocQueryStringFindExecutable 更可靠(它也不需要现有文件):visualstudiomagazine.com/articles/2009/10/13/…。至于 ASSOCF_INIT_IGNOREUNKNOWN 标志,如果您需要 Win7 之前的支持,我实际上喜欢您的想法,即使用某些 GUID 作为扩展来获取“无关联”处理程序的已删除答案(实际上这是我看到您的第一个想法问题)。

以上是关于如何查找是不是可以通过 ShellExecute 打开文档?的主要内容,如果未能解决你的问题,请参考以下文章

MFC中如何关闭ShellExecute调用的外部执行程序?

ShellExecute 不打开默认 Web 浏览器

如何利用ShellExecute()函数,从后台打开一个网页

请问delphi中ShellExecute的功能,和直接用show有啥不同?

ShellExecute的返回值是进程的句柄吗

如何使用 ShellExecute 从 VBScript 将参数传递给批处理文件 [重复]