问题-在Linux上的Java中为某些奇怪的客户端获取.exe的文件版本。
解决方案-
我使用JNA库使用Java读取文件版本。鉴于以下给出的代码在Windows平台上运行良好,但在Linux docker映像上却抛出了以下错误。
“无法加载库'version':加载共享库libversion.so时出错:没有此类文件或目录加载共享库libversion.so时出错:没有此类文件或目录本机库(linux-x86-64 / libversion.so )在资源路径中找不到。..
private String GetFileVersion(String filePath) {
File fileToCheck = new File(filePath);
short[] rtnData = new short[4];
int infoSize = Version.INSTANCE.GetFileVersionInfoSize(fileToCheck.getAbsolutePath(), null);
Pointer buffer = Kernel32.INSTANCE.LocalAlloc(WinBase.LMEM_ZEROINIT, infoSize);
try {
Version.INSTANCE.GetFileVersionInfo(fileToCheck.getAbsolutePath(), 0, infoSize, buffer);
IntByReference outputSize = new IntByReference();
PointerByReference pointer = new PointerByReference();
Version.INSTANCE.VerQueryValue(buffer, "\\", pointer, outputSize);
VerRsrc.VS_FIXEDFILEINFO fileInfoStructure = new VerRsrc.VS_FIXEDFILEINFO(pointer.getValue());
rtnData[0] = (short) (fileInfoStructure.dwFileVersionMS.longValue() >> 16);
rtnData[1] = (short) (fileInfoStructure.dwFileVersionMS.longValue() & 0xffff);
rtnData[2] = (short) (fileInfoStructure.dwFileVersionLS.longValue() >> 16);
rtnData[3] = (short) (fileInfoStructure.dwFileVersionLS.longValue() & 0xffff);
return String.format("%s.%s.%s.%s", rtnData[0], rtnData[1], rtnData[2], rtnData[3]);
} catch (Exception exception) {
return null;
} finally {
Kernel32.INSTANCE.GlobalFree(buffer);
}
}
答案 0 :(得分:0)
尽管我怀疑这是您实际上需要知道的,但我将首先回答您提出的问题。
不同的可执行文件格式的类型编码在文件的前几个字节中。例如,this Wikipedia页面中描述了ELF文件(可执行文件,共享库)。
因此,有多种方法可以找出Java中哪种可执行文件:
file
命令并编写一些Java代码以在每个库上运行file
并解析输出。我认为您实际上需要做的事情有所不同:
libversion.so
或linux-x86-64/libversion.so
。 (该文件很可能是符号链接。请遵循它。)file
,以检查它是否是正确的库。它们必须为32或64位对应于您正在运行的JVM ,以及用于平台的正确ABI和ISA。-Djava.library.path=...
JVM选项设置路径。有关库加载的更多信息,请参见"java.library.path – What is it and how to use"。
(绝对不需要“从Java中”或“在Java中”执行步骤2。)
答案 1 :(得分:0)
我想我终于弄清楚了你在做什么。
您使用的Version
实际上来自软件包com.sun.jna.platform.win32
。它不是JNA库(jna.jar)的一部分。我认为它实际上是jna-platform.jar的一部分。如果我理解正确,那就是Windows COM dll生成的JNA适配器库。
如果我没错,实际上您将需要为Linux平台编译和构建的Windows COM本机库来执行您想做的事情。
AFAIK,那是不可能的。
那你怎么做这项工作?基本上,您需要执行以下操作之一:
寻找现有的纯Java 库,以从Windows“ .exe”文件中提取版本信息。我认为您不太可能会找到一个。
找到Windows“ .exe”文件格式的规范,并编写自己的Java代码以提取版本信息。我没有寻找规范来查看它会做多少工作。
然后重写添加问题的代码以使用替代API。
我在其他答案中提到的“ libversion”文件不相关。这是另一回事。这是一条红鲱鱼。