如何获取Windows文件的详细信息?

我想获得“文件说明”和exe / dll / sys文件的“版权”,如右键单击该文件并select属性时在“详细信息”选项卡中所示。

使用Windows API,您可以调用VerQueryValue来获取该信息。 JNA有一个访问这个名为Version的 API的类。

这个其他的问题有一些代码示例,可以让你开始:

获取.exe的版本信息

这个有一个可以翻译成JNA的产品名称的C代码示例:

如何从Visual C ++中的版本资源中读取数据

这显然只适用于Windows。 如果你想要可移植的东西,你可以使用pecoff4j来自己解析可执行文件。 它声称能够解析PE(Portable Executable)的资源部分中的版本信息。


看来pecoff4j不支持解析版本字符串,所以我分叉它在GitHub添加支持。 现在这个代码应该可以工作

 import java.io.IOException; import org.boris.pecoff4j.PE; import org.boris.pecoff4j.ResourceDirectory; import org.boris.pecoff4j.ResourceEntry; import org.boris.pecoff4j.constant.ResourceType; import org.boris.pecoff4j.io.PEParser; import org.boris.pecoff4j.io.ResourceParser; import org.boris.pecoff4j.resources.StringFileInfo; import org.boris.pecoff4j.resources.StringTable; import org.boris.pecoff4j.resources.VersionInfo; import org.boris.pecoff4j.util.ResourceHelper; public class Main { public static void main(String[] args) throws IOException { PE pe = PEParser.parse("C:/windows/system32/notepad.exe"); ResourceDirectory rd = pe.getImageData().getResourceTable(); ResourceEntry[] entries = ResourceHelper.findResources(rd, ResourceType.VERSION_INFO); for (int i = 0; i < entries.length; i++) { byte[] data = entries[i].getData(); VersionInfo version = ResourceParser.readVersionInfo(data); StringFileInfo strings = version.getStringFileInfo(); StringTable table = strings.getTable(0); for (int j = 0; j < table.getCount(); j++) { String key = table.getString(j).getKey(); String value = table.getString(j).getValue(); System.out.println(key + " = " + value); } } } } 

它将打印您需要的所有信息:

 CompanyName = Microsoft Corporation FileDescription = Notepad FileVersion = 6.1.7600.16385 (win7_rtm.090713-1255) InternalName = Notepad LegalCopyright = © Microsoft Corporation. All rights reserved. OriginalFilename = NOTEPAD.EXE ProductName = Microsoft® Windows® Operating System ProductVersion = 6.1.7600.16385 

不是一个明确的答案,但这里是你可以尝试的解释。

请注意,这需要您使用JDK 7+。

由JDK定义的标准属性( DosFileAttributeViewPosixFileAttributeViewAclFileAttributeView )不包含用户定义的元数据。

你想要的是试着看看你的文件系统是否支持UserDefinedFileAttributeView 。 如果你有一些运气,它会; 如果你有更多的运气,你会在那里定义你的属性。

这是我的系统上的一个小例子(Ubuntu 14.04;文件系统是btrfs)。 我在shell上输入了这一行:

 setfattr -n user.comment -v "home sweet home" $HOME 

然后你可以阅读这个(注意:Java 8代码):

 public final class Attr { public static void main(final String... args) throws IOException { final Path home = Paths.get(System.getProperty("user.home")); final UserDefinedFileAttributeView view = Files.getFileAttributeView( home, UserDefinedFileAttributeView.class); if (view != null) view.list().forEach(name -> readAttr(view, name)); } private static void readAttr(final UserDefinedFileAttributeView view, final String name) { final ByteBuffer buf = ByteBuffer.allocate(1024); final CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder(); try { view.read(name, buf); buf.flip(); System.out.println(name + ": " + decoder.decode(buf).toString()); } catch (IOException e) { throw new RuntimeException("exceptions in lambdas suck", e); } } } 

这打印:

 comment: home sweet home 

正如javadoc所说,这是高度依赖于系统的。 请注意,通过名称读取属性的唯一方法是将其读入ByteBuffer (不需要扩展文件属性为文本)。