2009-08-12 80 views
4

我想检查一个特定的文件是否可以通过ShellExecute成功“打开”,因此我试图使用AssocQueryString来发现它。如何通过ShellExecute查找文档是否可以打开?

例子:

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?”对话。

显然我想隐藏最终用户的* p *,但是简单地将返回的字符串与常量进行比较看起来像是一种丑陋,蛮力和脆弱的方式。

此外,黑客注册表完全禁用此对话框不是一个好主意。

什么是更好的选择?

回答

4

我总是使用FindExecutable()来获取给定文档的注册申请。

+0

谢谢 - 完美的作品,如果没有注册申请,就会“正常”失败。踢自己找不到这个... – Roddy 2009-08-12 14:35:57

+0

太棒了,很高兴它解决了你的问题:-) – fhe 2009-08-12 15:00:56

+0

由于Samba性能问题,不得不重新审视这个问题。发布了我现在在下面使用的答案。 – Roddy 2011-07-01 16:38:02

3

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

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

这有几个重要的优点超过使用FindExecutable()

  • 它可以只用文件扩展工作,而FindExecutable需要对指定类型的现有文件完整路径。
  • 因为它不访问文件,所以Samba和其他网络存储的速度要快得多。在我的测试中,通过Samba在包含〜3000个文件的目录中的一个文件上调用FindExecutable()花费了> 1秒。
+1

我很困惑。你最初说你对Vista有问题,现在你说你有一个可行的解决方案,使用ASSOCF_INIT_IGNOREUNKNOWN标志,这个标志是根据MSDN在Windows 7中引入的。http://msdn.microsoft.com/en-us/library/ windows/desktop/bb762471(v = vs.85).aspx – RenniePet 2012-07-26 01:24:56

+0

是的,'AssocQueryString'比'FindExecutable'更可靠(它也不需要现有的文件):http://visualstudiomagazine.com/articles/2009 /10/13/finding-an-associated-executable.aspx。至于ASSOCF_INIT_IGNOREUNKNOWN标志,如果你需要Win7之前的支持,我实际上喜欢你的想法,在删除的答案中使用一些GUID作为扩展来获得“无关联”处理程序(实际上这是我第一次想到当我看到你的题)。 – 2014-11-08 11:13:06

相关问题