回到Windows XP时代,可以使用以下代码来判断扩展名是否存在文件关联:
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
}
但是,自Windows 8起,AssocQueryString
API返回S_OK
而buffPath
设置为C:\WINDOWS\system32\OpenWith.exe
,如果它找不到任何内容。
现在有更好的方法来确定文件扩展名没有Shell关联吗?
PS。我不想只将文件名与OpenWith.exe
进行比较。如果有一个合法的可执行文件就是这样......那一定有更好的方法。
答案 0 :(得分:2)
我想我明白了。诀窍是使用正确的标志。这似乎适用于XP及以上版本:
WCHAR wbuffPath[MAX_PATH] = {0};
DWORD dwszBuffPath = MAX_PATH;
HRESULT hR = ::AssocQueryStringW(ASSOCF_INIT_IGNOREUNKNOWN,
ASSOCSTR_EXECUTABLE,
L".weirdassextension",
NULL,
wbuffPath,
&dwszBuffPath);
if(hR == 0x80070483) // HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION)
{
//The association is missing
}
那里还有另外一个技巧,花了我一些时间才弄清楚 - 不要使用AssocQueryStringA()
。 AssocQueryStringA()
的垫片将其传递的字符串参数转换为Unicode在XP中存在一个错误(以及evidently in Vista),这将使该API在这些操作系统上失败。因此,如果你进行自己的ANSI-to-Unicode转换并调用AssocQueryStringW()
,问题就会消失(显然14年时间不足以让微软修复这个错误?)。