如何确定是否可以通过 ShellExecute 打开文档?

发布于 2024-08-02 05:13:42 字数 841 浏览 1 评论 0 原文

我想检查是否可以通过 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 无法打开”的原因此文件: 使用 Web 服务查找正确的程序?"对话。

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

另外,破解注册表以完全禁用此对话框并不是一个好主意。

什么是更好的选择?

I want to check if a particular file can be successfully "OPEN"ed via ShellExecute, so I'm attempting to use AssocQueryString to discover this.

Example:

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);

Now, this almost works. If there's a registered application, I get the string.

But, there's a catch: On Vista, even if there is no registered application, It returns that the app c:\Windows\System32\shell32.dll is associated, which is the thing that brings up the 100% useless "Windows cannot open this file: Use the Web service to find the correct program?" dialog.

Obviously I want to hide that peice of cr*p from end users, but simply comparing the returned string to a constant seems like an ugly, brute-force and fragile way of doing it.

Also, hacking the registry to totally disable this dialog isn't a great idea.

What's a better option?

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

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

发布评论

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

评论(2

惯饮孤独 2024-08-09 05:13:42

I always use FindExecutable() to get the registered application for a given document.

一身骄傲 2024-08-09 05:13:42

还有另一种方法可以实现此目的,即使用 ASSOCF_INIT_IGNOREUNKNOWN 选项标志和 AssocQueryString()

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

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

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

There is another way to do this, using the ASSOCF_INIT_IGNOREUNKNOWN option flag with AssocQueryString().

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

This has a couple of important advantages over using FindExecutable()

  • It can work with just the file extension, while FindExecutable needs a full path to an existing file of the specified type.
  • Because it's not accessing the file, it's much faster with Samba and other network storage. Calling FindExecutable() on one file in a directory containing ~3000 files via Samba took > 1 second in my tests.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文