在 JNA 中使用 Java 中的 SHGetFileInfo
Use SHGetFileInfo in Java with JNA
我尝试使用 JNA 将 SHGetFileInfo 函数从 Shell32 翻译成 Java,并使用 C# 代码和 this 作为参考
虽然在 C# 代码中 psfi.iIcon 在我翻译的 Java 代码中是 432 psfi.iIcon 是 0。如果我是对的,对于同一个文件,无论哪个文件,它们都应该相同我使用的语言,他们不应该吗?
我的Java代码:
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");
}
}
我有没有做错什么基本的事情?我是 JNA 和 Windows 函数
的新手
在备注部分下,有这条信息,恕我直言,这可能是您问题的根源
You must initialize Component Object Model (COM) with CoInitialize
or
OleInitialize
prior to calling SHGetFileInfo
.
这是一个非常简单的调用
CoInitialize(null);
正如 DanielWiddis 在评论中指出的那样,根据文档
New applications should call CoInitializeEx
instead of CoInitialize
和
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
例子
CoInitializeEx(null, 0);
CoUninitialize();
我尝试使用 JNA 将 SHGetFileInfo 函数从 Shell32 翻译成 Java,并使用 C# 代码和 this 作为参考
虽然在 C# 代码中 psfi.iIcon 在我翻译的 Java 代码中是 432 psfi.iIcon 是 0。如果我是对的,对于同一个文件,无论哪个文件,它们都应该相同我使用的语言,他们不应该吗?
我的Java代码:
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");
}
}
我有没有做错什么基本的事情?我是 JNA 和 Windows 函数
的新手在备注部分下,有这条信息,恕我直言,这可能是您问题的根源
You must initialize Component Object Model (COM) with
CoInitialize
orOleInitialize
prior to callingSHGetFileInfo
.
这是一个非常简单的调用
CoInitialize(null);
正如 DanielWiddis 在评论中指出的那样,根据文档
New applications should call
CoInitializeEx
instead ofCoInitialize
和
To close the COM library gracefully, each successful call to
CoInitialize
orCoInitializeEx
, including those that returnS_FALSE
, must be balanced by a corresponding call toCoUninitialize
例子
CoInitializeEx(null, 0);
CoUninitialize();