Going back to the days of Windows XP one could use the following code to tell if there's no file association existed for an extension:
TCHAR buffPath[MAX_PATH] = {0};
DWORD dwszBuffPath = MAX_PATH;
HRESULT hR = ::AssocQueryString(
ASSOCF_NOFIXUPS | ASSOCF_VERIFY,
ASSOCSTR_EXECUTABLE,
_T(".weirdassextension"),
NULL,
buffPath,
&dwszBuffPath);
if(hR != S_OK &&
hR != E_POINTER)
{
//Association does not exist
}
But since Windows 8, the AssocQueryString
API returns S_OK
and buffPath
is set to something like C:\WINDOWS\system32\OpenWith.exe
if it doesn't find anything.
Is there a better way now to determine that file extension has no Shell association?
PS. I do not want to just compare the file name to OpenWith.exe
. What if there's a legit executable called just that... There must be a better way.
I think I got it. The trick was to use the correct flags. This seems to work from XP and up:
There's one other trick there, that took me some time to figure out -- DO NOT use
AssocQueryStringA()
. The shim forAssocQueryStringA()
that converts its passed string parameters to Unicode has a bug in XP (and evidently in Vista as well) that will make that API fail on those OS. So, if you do your own ANSI-to-Unicode conversion and callAssocQueryStringW()
the problem will go away (Evidently 14 years is not enough time for Microsoft to fix that bug?).