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

时间:2014-05-24 13:17:01

标签: java windows file

我想获取exe / dll / sys文件的“文件描述”和“版权”,如右键单击文件并选择属性时,在“详细信息”选项卡中显示。

2 个答案:

答案 0 :(得分:5)

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

这个问题有一些代码示例可以帮助您入门:

Get Version Info for .exe

这个有一个读取产品名称的C代码示例,您可以将其转换为JNA:

How do I read from a version resource in Visual C++

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


似乎pecoff4j不支持解析版本字符串,所以我forked it on 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

答案 1 :(得分:0)

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

请注意,这需要您使用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(不要求扩展文件属性为文本)。