在Windows 10中,有没有办法判断一个文件扩展名是否有真正的关联?

后端开发 2026-07-08

看起来Windows 10倾向于在查询未关联的文件扩展名的处理程序时返回回退的“Open With”处理程序的位置,因此这个 GetAssociatedExecutable() 函数对于未知扩展名不会返回 null

private static string? getAssocString(string assoc, uint type) {
    uint length = 0;

    uint result = AssocQueryString(
        0,
        type,
        assoc,
        null,
        null!,
        ref length
    );

    if (result != S_FALSE && result != S_OK) {
        return null;
    }

    var sb = new StringBuilder((int)length);

    result = AssocQueryString(
        0,
        type,
        assoc,
        null,
        sb,
        ref length
    );

    return result == 0 ? $"{sb}" : null;
}

public static string? GetAssociatedExecutable(this string filePath) {
    string extension = Path.GetExtension(filePath);

    // Check ProgID first
    var progId = getAssocString(extension, ASSOCSTR_PROGID);
    // ^ For unknown extensions, gives: C:\WINDOWS\system32\OpenWith.exe "%1"
    if (string.IsNullOrEmpty(progId)) {
        return null;
    }

    // Resolve executable from ProgID
    return getAssocString(extension, ASSOCSTR_EXECUTABLE);
}

有没有可以查询的Win32 API,能够告诉我一个文件扩展名是否有正确的关联处理程序,而不仅仅是回退的“Open With”处理程序?

解决方案

感谢一位评论者(谢谢!)让我发现可以传入 ASSOCF_INIT_IGNOREUNKNOWN 标志来阻止Windows对未知文件类型返回OpenWith.exe。现在这就实现了我的需求:

private const uint S_OK = 0x0;
private const uint S_FALSE = 0x1;
private const uint ASSOCF_INIT_IGNOREUNKNOWN = 0x400;

// ...

private static string? getAssocString(string assoc, uint type) {
    uint length = 0;
    uint flags = 0;

    flags |= ASSOCF_INIT_IGNOREUNKNOWN;

    uint result = AssocQueryString(
        flags,
        type,
        assoc,
        null,
        null!,
        ref length
    );

    if (result != S_FALSE && result != S_OK) {
        return null;
    }

    var sb = new StringBuilder((int)length);

    result = AssocQueryString(
        flags,
        type,
        assoc,
        null,
        sb,
        ref length
    );

    return result == 0 ? $"{sb}" : null;
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章