Get Version Info for a .DLL using Java (JNA)

I want to get the version info for an .DLL 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

Java Native Access (JNA) provides Java programs easy access to native shared libraries without using the Java Native Interface. JNA’s design aims to provide native access in a natural way with a minimum of effort.

jna

You need to download the jna.jar and platform.jar from here to run the following code:

package de.eknori.jna;

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;

/**
 * @author Ulrich
 * 
 */
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);
	}

	/**
	 * 
	 */
	public 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);
		}
	}

	private String sFileName;
	private String sVersionNumber;

	/**
	 * 
	 */
	public FileVersionInfo() {
	}

	/**
	 * 
	 */
	public FileVersionInfo(String fname) {
		this.sFileName = fname;
	}

	/**
	 *
	 */
	private void _getVersion() {

		int versionlength = Version.INSTANCE.GetFileVersionInfoSizeW(
				this.sFileName, 0);

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

		PointerByReference lplpBuffer = new PointerByReference();
		IntByReference puLen = new IntByReference();

		@SuppressWarnings("unused")
		boolean FileInfoResult = Version.INSTANCE.GetFileVersionInfoW(
				this.sFileName, 0, versionlength, lpData);

		@SuppressWarnings("unused")
		int verQueryVal = Version.INSTANCE.VerQueryValueW(lpData, "\\",
				lplpBuffer, puLen);

		VS_FIXEDFILEINFO lplpBufStructure = new VS_FIXEDFILEINFO(
				lplpBuffer.getValue());
		lplpBufStructure.read();
		StringBuilder sb = new StringBuilder();
		sb.append((short) (lplpBufStructure.dwFileVersionMS >> 16));
		sb.append(".");
		sb.append((short) (lplpBufStructure.dwFileVersionMS & 0xffff));
		sb.append(".");
		sb.append((short) (lplpBufStructure.dwFileVersionLS >> 16));
		sb.append(".");
		sb.append((short) (lplpBufStructure.dwFileVersionLS & 0xffff));
		this.sVersionNumber = sb.toString();
	}

	/**
	 * 
	 */
	public void setFileName(String fname) {
		this.sFileName = fname;
	}

	/**
	 * 
	 */
	public String getVersionNumber() {
		this._getVersion();
		return sVersionNumber;
	}

	/**
	 * 
	 */
	public static void main(String[] args) throws IOException {
		// FileVersionInfo fv = new FileVersionInfo();
		// fv.setFileName("c:\\tools\\sample.dll");
		FileVersionInfo fv = new FileVersionInfo("c:\\tools\\sample.dll");
		System.out.println(fv.getVersionNumber());

	}
}