Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Version Info for .exe

Tags:

java

version

Does anybody know how got get the version info for a executable/file via Java. The scenario is that I have a file on my local system and if the version on the server is newer then the one on my system I need to download the file from the server.

like image 207
GEverding Avatar asked Aug 02 '11 20:08

GEverding


4 Answers

For reference, a modified version of the code by GEverding, with JNA 4, using com.sun.jna.platform.win32

package examples;

import java.io.IOException;

import com.sun.jna.Memory;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.VerRsrc.VS_FIXEDFILEINFO;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;

public class FileVersion {

    public static void main(String[] args) throws IOException {

        String filePath = "C:\\Test\\chromeinstall.exe";

        IntByReference dwDummy = new IntByReference();
        dwDummy.setValue(0);

        int versionlength =
                com.sun.jna.platform.win32.Version.INSTANCE.GetFileVersionInfoSize(
                        filePath, dwDummy);

        byte[] bufferarray = new byte[versionlength];
        Pointer lpData = new Memory(bufferarray.length);
        PointerByReference lplpBuffer = new PointerByReference();
        IntByReference puLen = new IntByReference();

        boolean fileInfoResult =
                com.sun.jna.platform.win32.Version.INSTANCE.GetFileVersionInfo(
                        filePath, 0, versionlength, lpData);

        boolean verQueryVal =
                com.sun.jna.platform.win32.Version.INSTANCE.VerQueryValue(
                        lpData, "\\", lplpBuffer, puLen);

        VS_FIXEDFILEINFO lplpBufStructure = new VS_FIXEDFILEINFO(lplpBuffer.getValue());
        lplpBufStructure.read();

        int v1 = (lplpBufStructure.dwFileVersionMS).intValue() >> 16;
        int v2 = (lplpBufStructure.dwFileVersionMS).intValue() & 0xffff;
        int v3 = (lplpBufStructure.dwFileVersionLS).intValue() >> 16;
        int v4 = (lplpBufStructure.dwFileVersionLS).intValue() & 0xffff;

        System.out.println(
                String.valueOf(v1) + "." +
                        String.valueOf(v2) + "." +
                        String.valueOf(v3) + "." +
                        String.valueOf(v4));
    }
}
like image 115
Antonis Zafiropoulos Avatar answered Nov 10 '22 12:11

Antonis Zafiropoulos


Due to portability issues I believe this kind of information is not actually available in java unless you access it using a less portable approach.

For example you could write a wrapper using JNI and C++ and use the GetFileVersionInfo API (see also this JavaWorld tip) of Windows to get that kind of information from the exe. Another approach would be to use a totally external application that outputs the version of the file and use the Runtime class to create a process and interact with that application.

Other approaches would require having access to the server and providing version checking from server side:

  • files contain the version number in their name,
  • save a separate file accessible to java that can provide the current version
  • save the date of the download on server side and checking if the current version is newer than the date when the last one was downloaded
  • check the md5 to see if the version is different, in case the server can contain only versions newer or equally as new as the client one
like image 27
virlan2004 Avatar answered Nov 10 '22 11:11

virlan2004


After spending hours online and coding I found a solution using JNA to get the Version Information for a file.

import com.sun.jna.Library;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.win32.W32APIOptions;
import java.io.IOException;


public class FileVersionInfo
{
    interface Version extends Library {

        Version INSTANCE = (Version) Native.loadLibrary("Version", Version.class, W32APIOptions.UNICODE_OPTIONS);

        public int GetFileVersionInfoSizeW(String lptstrFilename, int dwDummy);

        public boolean GetFileVersionInfoW(String lptstrFilename, int dwHandle,
            int dwLen, Pointer lpData);

        public int VerQueryValueW(Pointer pBlock, String lpSubBlock,
            PointerByReference lplpBuffer, IntByReference puLen);

    }

    static class VS_FIXEDFILEINFO extends com.sun.jna.Structure {
        public int dwSignature;
        public int dwStrucVersion;
        public int dwFileVersionMS;
        public int dwFileVersionLS;
        public int dwProductVersionMS;
        public int dwProductVersionLS;
        public int dwFileFlagsMask;
        public int dwFileFlags;
        public int dwFileOS;
        public int dwFileType;
        public int dwFileSubtype;
        public int dwFileDateMS;
        public int dwFileDateLS;

           public VS_FIXEDFILEINFO(com.sun.jna.Pointer p){
                super(p);
           }
    }
    public static void main(String[] args) throws IOException {

        int dwDummy = 0;
        int versionlength = Version.INSTANCE.GetFileVersionInfoSizeW(
                "C:\\Test\\chromeinstall.exe", dwDummy);

        byte[] bufferarray = new byte[versionlength];
        Pointer lpData = new Memory(bufferarray.length);    

        PointerByReference lplpBuffer = new PointerByReference();
        IntByReference puLen = new IntByReference();
        boolean FileInfoResult = Version.INSTANCE.GetFileVersionInfoW(
                "C:\\Test\\chromeinstall.exe",
                0, versionlength, lpData);
        System.out.println(FileInfoResult);
        int verQueryVal = Version.INSTANCE.VerQueryValueW(lpData,
                "\\", lplpBuffer,
                puLen);

        VS_FIXEDFILEINFO lplpBufStructure = new VS_FIXEDFILEINFO(
                lplpBuffer.getValue());
        lplpBufStructure.read();

        short[] rtnData = new short[4];
        rtnData[0] = (short) (lplpBufStructure.dwFileVersionMS >> 16);
        rtnData[1] = (short) (lplpBufStructure.dwFileVersionMS & 0xffff);
        rtnData[2] = (short) (lplpBufStructure.dwFileVersionLS >> 16);
        rtnData[3] = (short) (lplpBufStructure.dwFileVersionLS & 0xffff);

        for (int i = 0; i < rtnData.length; i++) {
            System.out.println(rtnData[i]);
        }

} 
like image 9
GEverding Avatar answered Nov 10 '22 10:11

GEverding


If you mean the information you get in Property->Details on Windows, bear in mind that it's platform dependent! That being said SIGAR has Java bindings and a FileVersionInfo class that seems close to what you need.

like image 2
Vlad Avatar answered Nov 10 '22 11:11

Vlad