在Linux上获取java中.exe的文件版本
问题-在Linux上为一些奇怪的客户端获取java中的.exe文件版本 溶液- 我使用JNA库使用Java读取文件版本。下面给出的代码在windows平台上运行良好,但在Linux docker映像上抛出以下错误 “无法加载库“版本”:加载共享库libversion时出错。so:没有此类文件或目录加载共享库libversion时出错。so:在资源路径中找不到此类文件或目录本机库(linux-x86-64/libversion.so)。”在Linux上获取java中.exe的文件版本,java,linux,docker,Java,Linux,Docker,问题-在Linux上为一些奇怪的客户端获取java中的.exe文件版本 溶液- 我使用JNA库使用Java读取文件版本。下面给出的代码在windows平台上运行良好,但在Linux docker映像上抛出以下错误 “无法加载库“版本”:加载共享库libversion时出错。so:没有此类文件或目录加载共享库libversion时出错。so:在资源路径中找不到此类文件或目录本机库(linux-x86-64/libversion.so)。” 我将首先回答你提出的问题,尽管我怀疑这是你真正需要知道的
我将首先回答你提出的问题,尽管我怀疑这是你真正需要知道的 不同可执行文件格式的类型在文件的前几个字节中编码。例如,ELF文件(可执行文件、共享库)在Wikipedia页面中进行了描述 因此,有很多方法可以找出Java中哪种类型的可执行文件:
file
命令,编写一些Java代码在每个库上运行file
,并解析输出我认为你实际上需要做的是有点不同:
libversion.so
或linux-x86-64/libversion.so
。(该文件很可能是一个符号链接。请遵循它。)文件
,检查它是否是正确的库类型。它们需要是32位或64位,对应于您正在运行的JVM,以及平台的正确ABI和ISA-Djava.library.path=…
JVM选项设置路径(绝对没有必要在Java中执行步骤2“从”或“在”中)。我想我终于弄明白了你在做什么 您正在使用的
版本实际上来自包com.sun.jna.platform.win32
。它不是JNA库(JNA.jar)的一部分。我认为它实际上是jna-platform.jar的一部分。如果我理解正确,那就是为Windows COM DLL生成的JNA适配器库
如果我没有弄错的话,您实际上需要为Linux平台编译和构建Windows COM本机库来完成您要做的事情
哎呀,那是不可能的
那你怎么能做到这一点呢?基本上,您需要执行以下操作之一:
- 查找现有的纯Java库,用于从Windows“.exe”文件提取版本信息。我认为你不大可能找到一个
- 查找Windows“.exe”文件格式的规范,并编写自己的Java代码来提取版本信息。我还没有寻找规格,看看有多少工作将是
然后重写添加问题的代码以使用替代API
我在另一个答案中提到的“libversion”文件与此无关。这是另外一回事。这是一个令人费解的问题。“…没有这样的文件或目录…”向我表示文件路径不正确,或者容器中不存在目标文件。从Win到*nix文件路径可能是一种痛苦。仔细检查资源的位置。嘿@DavidJEddy,我不是Java/linux专家。你能帮我解决这个问题吗?这个“版本”类来自JNA库,我无法控制它。遗憾的是,我对JNA不熟悉。尽管您似乎遇到的问题是文件路径/文件是否存在。应用程序正在查找一个文件,但该文件在给定位置不存在。@DavidEddy,请删除否决票好吗?我花了几个小时才把问题贴出来。你对这个问题做了什么研究?您是否有针对Linux编译的本机代码版本?它是否安装在您的Linux机器上?在Linux机器上查找exe
文件的用例是什么?这是什么项目的一部分?你的问题缺少很多信息。嗨,谢谢你的时间。我需要访问.exe的文件版本,而不是内容类型。如果这些修复程序能帮助我在Linux上运行JNA,我将在第二部分中探讨第一步和第三步。对于作为JNA库一部分的“Version”类来说,这是一个例外。请让我知道,如果你知道一些替代方法。你说的文件版本是什么意思?你是说版本号吗?比如libvorbis.so.0->libvorbis.so.0.4.8?AFAIK,仅通过文件名和符号链接名提供。是的,我需要读取版本号。如果您有其他/更好的方法,请建议我。您可能需要下载libversion源代码,并在Linux机器上构建和安装它。我无法识别任何包含它的Linux包。但我不相信这能解决你的问题。下载libversion不会有帮助。这是一个错误的答案,请看我的另一个答案。我同意你的观点,并且给出的代码在Linux上永远不会工作。linux上的文件
包没有提供文件版本
。我试图在linux上使用exiftool
包来读取文件版本
,但它的依赖性让我头疼。
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);
}
}