How to get Windows file details?

前端 未结 2 1062
灰色年华
灰色年华 2020-12-19 09:35

I want to get the \"File description\" and the \"Copyright\" of exe/dll/sys files, as showed in the \"Details\" tab when you right click the file and choose the properties.

相关标签:
2条回答
  • 2020-12-19 10:04

    Not a definitive answer but here is an explanation of what you can try.

    Note that this requires that you use JDK 7+.

    Attributes defined by the JDK as standard (DosFileAttributeView, PosixFileAttributeView, AclFileAttributeView) don't account for user-defined metadata.

    What you want is try and see whether your filesystem has support for UserDefinedFileAttributeView. If you have some luck, it will; if you have even more luck, you will have your attributes defined in there.

    Here is a small example on my system (Ubuntu 14.04; filesystem is btrfs). I typed this line on the shell:

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

    You can then read this using (note: Java 8 code):

    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);
            }
        }
    }
    

    This prints:

    comment: home sweet home
    

    As the javadoc says, this is HIGHLY system dependent. Note that the only method to read an attribute by name is to read it into a ByteBuffer (nothing requires that an extended file attribute be text).

    0 讨论(0)
  • 2020-12-19 10:06

    With Windows API you can call VerQueryValue to get that information. JNA has a class for accessing this API called Version.

    This other question has some code samples that can get you started:

    Get Version Info for .exe

    And this one has a C code sample of reading product name that you can translate into JNA:

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

    This obviously only works on Windows. If you want something portable, you might be able to use pecoff4j to parse the executable on your own. It claims to be able to parse the version information in the resource section of the PE (Portable Executable).


    It seems pecoff4j doesn't support parsing version strings, so I forked it on GitHub to add support for it. This code should now work:

    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);
                }
            }
        }
    
    }
    

    It will print all the information you need:

    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
    
    0 讨论(0)
提交回复
热议问题