Java get version of exe

Get Version Info for .exe

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.

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

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.

Читайте также:  Проверка знака числа python

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

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

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.

Читайте также:  Заголовок страницы

Источник

Получаем версию файла (exe, dll) с помощью java

Столкнулась я с такой проблемкой — как получить версию файла (exe и dll) на java. Ведь обычными стандартными средствами определить это нельзя, а только лишь можно узнать размер, дату последней модификации и некоторые другие свойства файла. Это описано тут.
Покопавшись на форумах и всё хорошенько прогуглив — нашла два таких выхода — JNI и JNA. Остановилась на втором варианте, так как на С++ писать специальную dll ну уж очень не хотелось, хотелось всё решить с помощью java и обращаться напрямую к version.dll (C:\WINDOWS\system32).
В итоге решение сводится к такой связке GetFileVersionInfo — GetFileVersionInfoSize — VerQueryValue. Долго пришлось поразбираться с функцией VerQueryValue — сложность была в том, что версии файлы зависят от языка и необходимо было хитрым способом получить LANGANDCODEPAGE. В итоге получился такой класс:

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.StdCallLibrary;
import java.io.IOException;

/**
*
* @author samozvanka
*/
public class Win32GetFileInformation
//+ declare before using
private static byte [] Hexhars = ««0123456789abcdef» .getBytes();

public String FileVersion;
private String LanguageCodePage;
private PointerByReference InfoData;

public interface Win32VersionDLL extends StdCallLibrary
Win32VersionDLL INSTANCE = (Win32VersionDLL) Native.loadLibrary(
«Version» , Win32VersionDLL. class );

Integer GetFileVersionInfoSizeA( String FilePath, IntByReference Handle);

Boolean GetFileVersionInfoA( String FilePath, int Handle, int InfoSize,
PointerByReference InfoData);

Boolean VerQueryValueA(PointerByReference InfoData,
String VersionInformation, PointerByReference VersionData,
IntByReference DataSize);
>

public void Win32GetFileInformation( String FilePath) throws IOException
IntByReference unusedParam = new IntByReference();

int infoSize = Win32VersionDLL.INSTANCE.GetFileVersionInfoSizeA(FilePath, unusedParam);
if (infoSize == 0)
throw new IOException( «File does not exist or has no information.» );
>

this .InfoData = new PointerByReference();

Boolean success = Win32VersionDLL.INSTANCE.GetFileVersionInfoA
(
FilePath,
unusedParam.getValue(),
infoSize,
this .InfoData
);

//+ Assert(success, «GetFileVersionInfoA in Win32GetFileInformation is failed»)

PointerByReference versionDataByRef = new PointerByReference();
IntByReference dataSize = new IntByReference();
Pointer versionDataPointer = null ;

// Retrieve the language information
success = Win32VersionDLL.INSTANCE.VerQueryValueA
(
this .InfoData,
«\\VarFileInfo\\Translation» ,
versionDataByRef,
dataSize
);

//+ Assert(success, «VerQueryValueA in Win32GetFileInformation is failed»)

System. out .println( «DataSize.getValue() #0000ff»>byte [] codePageBytes = versionDataPointer.getByteArray(0, dataSize.getValue());
byte BSwap;
// swap 01 and 23
BSwap = codePageBytes[1];
codePageBytes[1] = codePageBytes[0];
codePageBytes[0] = BSwap;
BSwap = codePageBytes[3];
codePageBytes[3] = codePageBytes[2];
codePageBytes[2] = BSwap;
// got 1,0,3,2

this .LanguageCodePage = decode(codePageBytes).toUpperCase();

//// Retrieve file information
this .FileVersion = QueryValue( «FileVersion» );

System. out .println( «FileVersion #0000ff»>this .FileVersion);

private String QueryValue( String ValueName)
IntByReference dataSize = new IntByReference();
PointerByReference versionDataByRef = new PointerByReference();
Pointer versionDataPointer = null ;
Boolean success = Win32VersionDLL.INSTANCE.VerQueryValueA
(
this .InfoData,
«\\StringFileInfo\\» + this.LanguageCodePage + » \\ » + ValueName, //»
versionDataByRef,
dataSize
);

//+ Assert(success, «VerQueryValueA in Win32GetFileInformation is failed»)

versionDataPointer = versionDataByRef.getValue();
if (versionDataPointer == null )
return «» ;
>
else
versionDataPointer = versionDataByRef.getValue();
return versionDataPointer.getString();
>
>

private static String decode( byte [] encodedString)
StringBuilder result = new StringBuilder (2 * encodedString.length);

result.append(( char ) Hexhars[v >> 4]);
result.append(( char ) Hexhars[v & 0xf]);
>

return result.toString();
>
>

* This source code was highlighted with Source Code Highlighter .

Вдруг кому пригодится. И если есть другие какие то несложные реализации этого, то хотелось бы их узнать.

Источник

Get Version Info for .exe

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

Solution 2

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

Solution 3

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

Solution 4

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.

Solution 5

I modified Antonis Zafiropoulos’s answer and made a handy class you can just drop into your project. Note that the fileInfoResult and verQueryVal lines must exist even though they don’t appear to do anything.

package yourpackage; 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 EXEFileInfo < public static int MAJOR = 0; public static int MINOR = 1; public static int BUILD = 2; public static int REVISION = 3; public static int getMajorVersionOfProgram(String path) < return getVersionInfo(path)[MAJOR]; >public static int getMinorVersionOfProgram(String path) < return getVersionInfo(path)[MINOR]; >public static int getBuildOfProgram(String path) < return getVersionInfo(path)[BUILD]; >public static int getRevisionOfProgram(String path) < return getVersionInfo(path)[REVISION]; >public static int[] getVersionInfo(String path) < IntByReference dwDummy = new IntByReference(); dwDummy.setValue(0); int versionlength = com.sun.jna.platform.win32.Version.INSTANCE.GetFileVersionInfoSize(path, 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(path, 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("Version: " + v1 + "." + v2 + "." + v3 + "." + v4); return new int[] < v1, v2, v3, v4 >; > > 

Источник

Оцените статью