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

muk1a3rh  于 2023-06-24  发布在  Windows
关注(0)|答案(1)|浏览(109)

回到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进行比较。如果有一个合法的可执行文件叫做...一定有更好的办法。

dxxyhpgq

dxxyhpgq1#

我想我明白了关键是要使用正确的旗帜。这似乎适用于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()的shim将其传递的字符串参数转换为Unicode,在XP(以及evidently in Vista)中有一个bug,这将使该API在这些操作系统上失败。所以,如果你自己做ANSI到Unicode的转换并调用AssocQueryStringW(),问题就会消失(显然14年的时间不足以让微软修复这个bug?)).

相关问题