フォーラムをざっと調べてすべてをうまく調べた後、そのような2つのソリューション、 JNIとJNAを見つけました。 C ++では特別なdllを作成したくなかったため、javaですべてを解決し、version.dll(C:\ WINDOWS \ system32)に直接アクセスしたかったため、2番目のオプションで停止しました。
その結果、ソリューションはそのようなバンドル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 .
突然誰かが重宝します。 そして、これの他の単純な実装がある場合、私はそれらを知りたいです。