How to determine if a shell verb is registered for a given file type?
Given a file extension, how would I query to see if any program is registered to handle a specific Shel开发者_运维技巧lExecute verb ("print"
in my case) without actually invoking said verb?
#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));
}
If you want to query the registry yourself (why?) you need to be able to handle several "redirections", off the top of my head:
- (Vista+) First check HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\%.ext%\UserChoice : (REG_SZ) "ProgId"
- If that key is empty, read HKCR\%.ext% : (REG_SZ) "" (default)
You should now have a ProgId, then check HKCR\%ProgId% : (REG_SZ) "CurVer", if it exists (and has a shell subkey) you found the "real" ProgId, if not, keep using the original ProgId.
You can now check for HKCR\%ProgId%\shell\%verb% (You really should check to see if it has a command subkey with a string, or a droptarget or dde values etc)
(XP+) If you did not find the verb under the progid:
- Check HKCR\SystemFileAssociations\%.ext%\shell\%verb%
(XP+) If you still have not found the verb, read HKCR\%.ext% : (REG_SZ) "PerceivedType", if non empty, check HKCR\SystemFileAssociations\%PerceivedType%\shell
If you still have not found the verb, check under HKCR\*
, HKCR\AllFilesystemObjects
and HKCR\Unknown
(Win7 added submenus etc, I have not taken those into consideration and I have probably left out some other steps, AFAIK not all of this is documented)
Even if you do all this, there could be a verb and you have not detected it, shell extensions can add verbs at run time and the only way to check for these is to use IContextMenu on the actual file...
I guess you could grovel the Registry.
Look up HKCU\Software\Classes\<.extension>
which should have a default value. Look this up HKCU\Software\Classes\<value>\Shell\<verb>\Command
. If you don't find the value under HKCU\Software\Classes
also try HKLM\Software\Classes
(or its alias HKCR
).
精彩评论