Use SHGetFileInfo in Java with JNA

Mano176 :

I tried to translate the SHGetFileInfo function from Shell32 into Java with JNA and used C# code and this as reference

While in the C# code psfi.iIcon is 432 in my translated Java code psfi.iIcon is 0. If I am right, for the same file they should be same no matter which language I use, shouldn't they?

My Java code:

public static void main(String[] args) {
    String path = "[PATH_TO_EXE]\\test.exe"; //Of 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");
    }
}

Is there anything fundemental that I did wrong? I'm new to JNA and Windows functions

LppEdd :

Under the Remarks section, there is this piece of information, which imho might be the source of your problem

You must initialize Component Object Model (COM) with CoInitialize or OleInitialize prior to calling SHGetFileInfo.

It's a pretty straightforward call

CoInitialize(null);

As DanielWiddis pointed out in the comments, per documentation

New applications should call CoInitializeEx instead of CoInitialize

And

To close the COM library gracefully, each successful call to CoInitialize or CoInitializeEx, including those that return S_FALSE, must be balanced by a corresponding call to CoUninitialize

Example

CoInitializeEx(null, 0);
CoUninitialize();

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=145331&siteId=1