Покопавшись на форумах и всё хорошенько прогуглив :) - нашла два таких выхода - JNI и JNA. Остановилась на втором варианте, так как на С++ писать специальную dll ну уж очень не хотелось, хотелось всё решить с помощью java и обращаться напрямую к version.dll (C:\WINDOWS\system32).
В итоге решение сводится к такой связке GetFileVersionInfo - GetFileVersionInfoSize - VerQueryValue. Долго пришлось поразбираться с функцией VerQueryValue - сложность была в том, что версии файлы зависят языка и необходимо было хитрым способом получить LANGANDCODEPAGE.В итоге получился такой класс:
package upload;
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() = " + dataSize.getValue());
versionDataPointer = versionDataByRef.getValue();
byte[] codePageBytes = versionDataPointer.getByteArray(0, dataSize.getValue());
byte BSwap;
// swap 0<->1 and 2<->3
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 = " + 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);
for (int i = 0; i < encodedString.length; i++)
{
int v = encodedString[i] & 0xff;
result.append((char) Hexhars[v >> 4]);
result.append((char) Hexhars[v & 0xf]);
}
return result.toString();
}
}
* This source code was highlighted with Source Code Highlighter.
Комментариев нет:
Отправить комментарий