给定一个文件扩展名,我将如何查询是否有任何程序已注册以处理特定的 ShellExecute 动词("print"在我的情况下)而不实际调用所述动词?
2 回答
#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\AllFilesystemObjects和HKCR\Unknown
(Win7 添加了子菜单等,我没有考虑到这些,我可能遗漏了一些其他步骤,AFAIK 并没有记录所有这些)
即使你做了所有这些,也可能有一个动词并且你没有检测到它,shell扩展可以在运行时添加动词,检查这些的唯一方法是在实际文件上使用 IContextMenu ...
我猜你可能会向注册表低头。
查找HKCU\Software\Classes\<.extension>哪个应该具有默认值。看看这个HKCU\Software\Classes\<value>\Shell\<verb>\Command。HKCU\Software\Classes如果您在也尝试HKLM\Software\Classes(或其别名)下找不到该值HKCR。