0

给定一个文件扩展名,我将如何查询是否有任何程序已注册以处理特定的 ShellExecute 动词("print"在我的情况下)而不实际调用所述动词?

4

2 回答 2

5
#include <windows.h>
#include <Shlwapi.h>
#include <stdio.h>

#if _WIN32_WINNT <= 0x0501
#define ASSOCF_INIT_IGNOREUNKNOWN   0x00000400 
#endif

BOOL AssocExtHasVerb(LPCTSTR dotExt,LPCTSTR verb) 
{
    HKEY hKey;
    HRESULT hr = AssocQueryKey(ASSOCF_INIT_IGNOREUNKNOWN,ASSOCKEY_SHELLEXECCLASS,dotExt,verb,&hKey);
    if (SUCCEEDED(hr)) 
    {
        RegCloseKey(hKey);
        return TRUE;
    }
    return FALSE;
}


void main() 
{
    LPCTSTR ext=".txt",verb="print";
    printf("%s:%s=%d\n",ext,verb,AssocExtHasVerb(ext,verb));
}

如果您想自己查询注册表(为什么?),您需要能够处理几个“重定向”,我不知道:

  • (Vista+) 首先检查 HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\%.ext%\UserChoice : (REG_SZ) "ProgId"
  • 如果该键为空,请阅读 HKCR\%.ext% : (REG_SZ) "" (默认)

你现在应该有一个 ProgId,然后检查 HKCR\%ProgId% : (REG_SZ) "CurVer",如果它存在(并且有一个 shell 子项)你找到了“真正的”ProgId,如果没有,继续使用原来的 ProgId。

你现在可以检查 HKCR\%ProgId%\shell\%verb% (你真的应该检查它是否有一个带有字符串的命令子键,或者一个 droptarget 或 dde ​​值等)

(XP+) 如果在 progid 下没有找到动词:

  • 检查 HKCR\SystemFileAssociations\%.ext%\shell\%verb%

(XP+) 如果还没有找到动词,阅读 HKCR\%.ext% : (REG_SZ) "PerceivedType",如果非空,检查 HKCR\SystemFileAssociations\%PerceivedType%\shell

如果您仍然没有找到动词,请HKCR\*HKCR\AllFilesystemObjectsHKCR\Unknown

(Win7 添加了子菜单等,我没有考虑到这些,我可能遗漏了一些其他步骤,AFAIK 并没有记录所有这些)


即使你做了所有这些,也可能有一个动词并且你没有检测到它,shell扩展可以在运行时添加动词,检查这些的唯一方法是在实际文件上使用 IContextMenu ...

于 2011-03-25T17:53:37.120 回答
2

我猜你可能会向注册表低头。

查找HKCU\Software\Classes\<.extension>哪个应该具有默认值。看看这个HKCU\Software\Classes\<value>\Shell\<verb>\CommandHKCU\Software\Classes如果您在也尝试HKLM\Software\Classes(或其别名)下找不到该值HKCR

于 2011-03-24T20:44:40.580 回答