在Java和JNA中使用SHGetFileInfo

时间:2019-03-17 14:50:26

标签: java c# winapi jna

我尝试使用JNA将Shell32的SHGetFileInfo函数转换为Java,并使用C#代码和this作为参考

在我翻译的Java代码psfi.iIcon中,C#代码psfi.iIcon中的值为432。如​​果我是对的,那么对于同一个文件,无论使用哪种语言,它们都应该相同,不是吗? / p>

我的Java代码:

public static void main(String[] args) {
    String path = "[PATH_TO_EXE]\\test.exe"; //Off course in my code I used the real path

    SHFILEINFO sfi = new SHFILEINFO();
    DWORD_PTR i = Shell32.INSTANCE.SHGetFileInfo(path, 0, sfi, sfi.size(), SHGFI.SysIconIndex);

    System.out.println(sfi.iIcon); //<-- Prints 0, should print 432
}

public static class SHGFI {
    static final int SysIconIndex = 0x000004000;
    static final int LargeIcon = 0x000000000;
    static final int UseFileAttributes = 0x000000010;
}

public interface Shell32 extends StdCallLibrary {
    Shell32 INSTANCE = Native.loadLibrary("shell32", Shell32.class, W32APIOptions.UNICODE_OPTIONS);
    DWORD_PTR SHGetFileInfo(String pszPath, int dwFileAttributes, SHFILEINFO psfi, int cbFileInfo, int uFlags);
}

public static class SHFILEINFO extends Structure {
    public HICON hIcon;
    public int iIcon;
    public DWORD dwAttributes;
    public char[] szDisplayName = new char[260];
    public char[] szTypeName = new char[80];

    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList("hIcon", "iIcon", "dwAttributes", "szDisplayName", "szTypeName");
    }
}

我做错了什么吗?我是JNA和Windows函数的新手

1 个答案:

答案 0 :(得分:3)

备注部分下,有这条信息,恕我直言可能是问题的根源

  

您必须使用CoInitialize初始化组件对象模型(COM)或   OleInitialize,然后再调用SHGetFileInfo

这是一个非常简单的电话

CoInitialize(null);

根据文档,DanielWiddis在评论中指出

  

新应用程序应调用CoInitializeEx而不是CoInitialize

  

要正常关闭COM库,每次成功调用   CoInitializeCoInitializeEx,包括返回S_FALSE的那些,   必须通过对CoUninitialize

的相应调用来平衡

示例

CoInitializeEx(null, 0);
CoUninitialize();