如何判断Windows XP后的操作系统上是否没有默认的文件扩展名关联?

时间:2016-02-07 04:59:15

标签: c++ windows winapi windows-shell windows-explorer

回到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_OKbuffPath设置为C:\WINDOWS\system32\OpenWith.exe,如果它找不到任何内容。

现在有更好的方法来确定文件扩展名没有Shell关联吗?

PS。我不想只将文件名与OpenWith.exe进行比较。如果有一个合法的可执行文件就是这样......那一定有更好的方法。

1 个答案:

答案 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年时间不足以让微软修复这个错误?)。