如何在Java中获取Windows 10文件/快捷方式的图标文件路径?
在Java中获取Windows 10文件/快捷方式的完整尺寸图标路径
要获取Windows系统中文件或快捷方式的完整尺寸图标对应的源文件路径,核心是调用Windows原生Shell API提取图标位置信息——Java本身没有直接访问系统图标资源的能力。以下是两种务实的实现方案:
一、使用JNA调用Shell32 API获取文件图标路径
JNA(Java Native Access)可让Java直接调用Windows DLL函数,无需编写JNI代码。
1. 引入JNA依赖
若用Maven,在pom.xml中添加:
<dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> <version>5.13.0</version> </dependency> <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna-platform</artifactId> <version>5.13.0</version> </dependency>
2. 编写代码获取图标路径
调用SHGetFileInfo函数,指定SHGFI_ICONLOCATION标志获取图标文件路径和索引,配合SHGFI_LARGEICON确保获取大尺寸图标对应信息:
import com.sun.jna.Native; import com.sun.jna.platform.win32.Shell32; import com.sun.jna.platform.win32.WinDef; import com.sun.jna.platform.win32.WinNT; import com.sun.jna.Structure; import java.util.Arrays; import java.util.List; public class IconPathGetter { public static class SHFILEINFO extends Structure { public WinDef.HICON hIcon; public int iIcon; public int 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"); } } public static void main(String[] args) { String filePath = "C:\\Windows\\notepad.exe"; // 替换为目标文件路径 SHFILEINFO shfi = new SHFILEINFO(); // 组合标志:获取图标位置 + 大尺寸图标 int flags = Shell32.SHGFI_ICONLOCATION | Shell32.SHGFI_LARGEICON; WinDef.HINSTANCE hInst = WinNT.HINSTANCE.NULL; Shell32.INSTANCE.SHGetFileInfo(filePath, 0, shfi, shfi.size(), flags); String iconFilePath = Native.toString(shfi.szDisplayName); int iconIndex = shfi.iIcon; System.out.println("图标文件路径: " + iconFilePath); System.out.println("图标索引: " + iconIndex); } }
代码会输出图标所在文件(如notepad.exe本身,或shell32.dll这类系统库)及对应图标索引。
二、解析快捷方式(.lnk)获取目标文件的图标路径
快捷方式本身不含图标,需先解析.lnk得到指向的目标路径,再对目标路径执行上述图标获取操作。
解析.lnk的代码示例
通过JNA的IShellLink接口解析快捷方式目标路径:
import com.sun.jna.platform.win32.*; import com.sun.jna.WString; import com.sun.jna.platform.win32.WinNT.HRESULT; public class LnkParser { public static String getLnkTarget(String lnkPath) { Shell32 shell32 = Shell32.INSTANCE; Ole32.INSTANCE.CoInitialize(null); IShellLink link = IShellLink.Util.createInstance(); IPersistFile file = link.queryInterface(IPersistFile.class); try { file.load(new WString(lnkPath), Shell32.STGM_READ); WinDef.PWSTR pwstr = new WinDef.PWSTR(); link.getPath(pwstr, WinDef.MAX_PATH, null, 0); return pwstr.getValue(); } catch (Exception e) { e.printStackTrace(); return null; } finally { file.release(); link.release(); Ole32.INSTANCE.CoUninitialize(); } } public static void main(String[] args) { String lnkPath = "C:\\Users\\Public\\Desktop\\Notepad.lnk"; // 替换为目标快捷方式路径 String targetPath = getLnkTarget(lnkPath); if (targetPath != null) { // 调用前面的图标获取方法处理targetPath System.out.println("快捷方式目标路径: " + targetPath); } } }
拿到目标路径后,复用第一部分代码即可获取对应图标路径。
注意事项
- 确保程序以足够权限运行,避免访问系统文件时出现权限问题。
- 不同文件类型的图标来源不同:可执行文件(.exe、.dll)通常内置图标;普通文档(.txt、.docx)的图标存储在系统Shell DLL中(如shell32.dll)。
- 若需提取具体尺寸的图标,可根据获取到的文件路径和索引,进一步调用
ExtractIconEx函数提取对应尺寸的图标资源。
内容的提问来源于stack exchange,提问作者Anonymous2840938028
相关产品推荐
相关产品推荐

