【问题标题】: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 的部分,但简单地将返回的字符串与常量进行比较似乎是一种丑陋、暴力和脆弱的做法。

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

什么是更好的选择?

【问题讨论】:

    标签: c++ winapi shellexecute


    【解决方案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 作为扩展来获取“无关联”处理程序的已删除答案(实际上这是我看到您的第一个想法问题)。
    猜你喜欢
    • 1970-01-01
    • 2014-04-04
    • 2020-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-07
    • 1970-01-01
    相关资源
    最近更新 更多